Archive for the ‘Announcements’ Category

Finishing up Swift From Two to Three


I’m getting close to wrapping up my latest little self-published Swift book. Like Playground Secrets and Documentation Markup, the book will be available on iTunes and LeanPub. It’s written for anyone who has stayed in Swift 2.3 so they could keep shipping code but who now is looking to move towards Swift 3.

Here are some sample pages to give you a feel for what’s coming up.

As always, if you have any feedback or requests, please let me know. Does this sound like a book you might purchase? I’d love to hear from you.

Thanks again for all the support you give me, my blog, and my books. It’s appreciated beyond measure.

Chris Lattner on wrapping up Swift 3, starting Swift 4

Chris Lattner writes on Looking back on Swift 3 and ahead to Swift 4.  Key tl;dr points:

  • Open source is great but you can’t make everyone happy.
  • Swift 3 in Fall 2016. Swift 3.x will release in Spring 2017. Swift 4 in Fall 2017, not counting minor releases for bugs/compatibility (e.g. 3.0.1)
  • Swift 4 must deliver its source stability promise, plus resilience, ABI, improving generics, strings, etc.
  • Syntactic sugar can wait and are the lowest-priority items.
  • Scheduling is hard. Goals aren’t promises of delivery. Scheduling and planning from the start will take priority.

Here is the message in full:

Hello Everyone,

The Swift 3 release is nearing completion, so it is time to look back on the release, learn from what happened, and use it to shape what we (the Swift community) do in the year ahead. Overall, Swift 3 is going to be an absolutely amazing release, and it is impressive how much got done. Thank you to everyone who contributed to making it happen. Instead of diving into a flurry of new proposals immediately, it is important to take stock of where we are, and look at the bigger picture.

Metapoint: this email is ridiculously long and covers multiple topics. Instead of replying to it directly, it is best to start new threads on individual topics that you’d like to discuss. Just tag them with “[Swift 4]” in the subject line.

Swift 3 Retrospective

Every year of Swift’s development has been completely different from the previous one, and I expect Swift 4 to continue this trend. With a goal of learning and improving year over year, here are some observations & retrospective about Swift 3:

  • Open source is pretty great. It has been incredible to see such a vibrant community working so well together, and to see you come together practically overnight. It is really fantastic to work with such a talented and enthusiastic group of people!
  • Open source also brings challenges. I think it is fair to say that “open design” is slower and less predictable than “closed design”. However, the end result is significantly better, and therefore the tradeoff is worth it. A big “Thank you!” goes out to everyone who helps improve Swift through the evolution process.
  • Software scheduling (particularly with open source) continues to be difficult-to-impossible to predict. We set off on Swift 3 with a lofty set of goals that had to be trimmed back later. It is good to have high goals, but we need to do a better job of communicating that “goals” are not “promises” so that people don’t feel misled.
  • The community benefits from keeping focus on a limited number of topics, because if there is too much going on, no one can follow and keep track of it all. It is important for the core team to be involved in key discussions up front. In the Swift 3 cycle, it was problematic that many folks had no time to follow the threads until after the review period completed.
  • Having clear goals is liberating. In the December/January timeframe in particular, we loosely scoped what sorts of ideas would fit into Swift 3, and embarked on several projects that ended up being far beyond what we could handle. Later in the release, we had very specific goals (for example, “no additive proposals”) which made it much easier for everyone to focus on what was important.
  • It is impossible to make everyone happy, particularly when discussing which features to pick up and prioritize* because that implicitly de-prioritizes something else. This is inevitable though, because there is no way that all the interesting work will fit into a one-year release cycle. Fortunately, there will “always be another release,” and each new release will have its share of big improvements.

With that as context, let’s look ahead!

Swift Release Plan

Over the next year, the core team expects to ship two major releases of Swift: Swift 3.x in Spring 2017 and Swift 4 in Fall 2017. In addition to the major releases, we will surely ship some minor releases (e.g. Swift 3.0.1) to fix bugs or service the needs of the corelibs or other projects.

Swift 4 Release Cycle Planning Approach

From our experience with Swift 3, we know we need to pick and choose what we’re going to tackle. For Swift 4, the primary goals are to deliver on the promise of source stability from 3.0 on, and to provide ABI stability for the standard library. As such, the core team has decided to take a two-stage approach to the next year:

Stage #1: Focus on the essentials required for Source and ABI stability, and keep reasonably strict focus on only that work. This means that any features that don’t fundamentally change the ABI of existing language features or imply an ABI-breaking change to the standard library will not be considered in this stage. For example, generics features like conditional conformance is an additive feature, but since it is expected to reshape much of the standard library it would be part of Stage 1. On the other hand, language support for regular expressions would not affect existing ABI nor cause major changes to existing standard library features, so it would not fit in Stage 1.

The work entailed by Stage 1 is non-trivial (explored in somewhat more detail below), and will probably keep us busy until the Spring.

Stage #2: As the design and implementation work on the Stage 1 features is cresting, we’ll scope and plan a few other large features based on how much time we have left. I’m optimistic that we’ll have time to pick up some of the long list of features explored below, but we won’t know which ones those are until we know how much time we have to develop them with.

In addition to new features, we also need to reevaluate accepted source breaking proposals that didn’t make it into Swift 3. These proposals will not necessarily be grandfathered in* we will need to evaluate them against the goals of Swift 4 and decide what to do with each of them on a case by case basis.

Finally, while it isn’t specifically related to swift-evolution, I want to call out quality & performance work. The core team wants to continue to improve quality, including fixing compiler bugs and improving error and warning diagnostics. Performance is also an ongoing area of critical development, including improving the performance of the generated code, improving the standard library implementation, speeding up compile time, etc. All of this work can happen in either stage.

Swift 4 Stage 1 Goals

With a focus on source and ABI stability, the core team had an initial discussion about what makes up the Stage 1 effort. Here are the features that we are prioritizing for Stage 1:

  • Source stability features: These should be relatively small, but important. For example, we need a “-std=swift3” sort of compiler flag. We may also add a way to conditionally enable larger efforts that are under development but not yet stable* in order to make it easier to experiment with them.
  • Resilience: This provides a way for public APIs to evolve over time, even in the face of ABI stability. For example, we don’t want the C++ “fragile base class” problem to ever exist in Swift. Much of the design and implementation work was done in the Swift 3 timeframe, but there are still major missing pieces, including the user-visible part of the model (e.g. new attributes).
  • ABI Details: There are a ton of small details that should be audited and improved in the code generation model. This is mostly relevant to swift-dev, and not specifically a swift-evolution topic.
  • Generics improvements needed by the standard library: I expect conditional conformances to be the very top of this list, and for recursive protocol requirements and more powerful associated type constraints to be close followers. However, the standard library gurus need to break down what is absolutely essential to finally eliminate the rest of the “_” protocols and manifest the public API of the standard library in the right way for the long term.
  • String re-evaluation: String is one of the most important fundamental types in the language. The standard library leads have numerous ideas of how to improve the programming model for it, without jeopardizing the goals of providing a unicode-correct-by-default model. Our goal is to be better at string processing than Perl!
  • Memory ownership model: Adding an (opt-in) Cyclone/Rust inspired memory ownership model to Swift is highly desired by systems programmers and folks who want predictable and deterministic performance (for example, in real time audio processing code). More pertinent to the goals of Swift 4, this feature is important because it fundamentally shapes the ABI. It informs code generation for “inout”, how low-level “addressors” work in the ABI, impacts the Swift runtime, and will have a significant impact on the type system and name mangling.

Each of these areas has had some thought put into them already, but are still a long way from being formal proposals. I expect and hope that they will turn into major discussions early in the Swift 4 cycle. Further, since we haven’t fully scoped what impacts ABI stability, there may be other specific additions as we learn more. Finally, it is also possible that we may choose to scope in specific small features that are high value to unblock SwiftPM or other projects.

Possible Swift 4 Stage 2 Efforts

As I mentioned above, at this point it is impossible to know what can be achieved in the Stage 2 timeframe, because we don’t know how long that timeframe is. The core team would also like to converge Swift 4 development earlier in its cycle than Swift 3 did, in order to fix more bugs late in the release and provide a longer bake time.

That said, I’m optimistic that we’ll be able to pick up and tackle some of the commonly requested new features. To give you an idea of some of them, here is a list. Please note that this is not a plan or commitment, it is just a laundry list of commonly requested features:

  • Reflection: The core team is committed to adding powerful dynamic features to Swift. For example, Swift 3 already added nearly all the infrastructure for data reflection (which is already used by the Xcode memory debugger). We should use this infrastructure to build out a powerful user-facing API. Similarly, we would like to design and build out the implementation for dynamic method reflection runtime + API support.
  • First class concurrency: Actors, async/await, atomicity, memory model, and related topics. This area is highly desired by everyone, as it will open the door for all sorts of new things on the client, server and more. We plan to start formal discussions about this in Phase 2, but it is unfortunately crystal clear that a new concurrency model won’t be done in time for the Swift 4 release. This is simply because it will take more than a 12 months to design and build, and we want to make sure to take time to do it right. It also makes sense for the memory ownership model to be better understood before taking this on.
  • Generics improvements: The generics manifesto includes many exciting enhancements to the generics system, many of which will not be specifically required for ABI stability of the standard library, but would make Swift generics more powerful and expressive.
  • .swiftmodule stability: At some point we need to stabilize the “.swiftmodule” binary file format (or replace it with a different mechanism) to allow 3rd party binary frameworks. This is a very large amount of work over and above what is required for ABI stability of the standard library.
  • New scripting features: Regular expressions, multi-line string literals, etc. Having these would make Swift much more appealing to the crowd doing scripting and those building web technologies, among others. They’d also help round out the String model.
  • Property behaviors: This feature promises to provide powerful abstractions over the existing property model. The deferred SE-0030 proposal describes this opportunity well.
  • So many others: Submodules, implicit promotions between numeric types, importing C++ APIs, hygenic macro system, guaranteed tail calls, making enums enumerable, typed ‘throws’, user defined attributes, abstract methods/classes, better SIMD support, ‘dynamic’ for non-@objc, data parallelism support, higher kinded types, …
  • Syntactic sugar: I won’t list them all, but there are a ton of other trivial to small proposals that frequently come up, typically things seen in other languages that solve specific problems. These are the lowest priority to tackle for Swift 4.

So there you go, an overly long email laying out some thoughts and ideas of what to do over the next year. One specific thing to keep in mind is that Swift 3 isn’t done yet. While source breaking changes are (nearly) done, there is still time for bug fixing and other quality work, and that is very important to the release.

I think it would be helpful for us to spend the immediate future discussing the general parameters of how we tackle the releases over the next year, then iron out the Stage 1 features conceptually. We should only start writing proposals when the specific design of them are well understood. The core team does not want to be in a situation where there are so many proposals floating around that we can’t keep track of them, or that they prevent tackling the large and important high priority projects in front of us.

Thank you. Again, please start new threads if you’d like to dive in more deeply into specific topics

End of Source Breaking Changes for Swift 3

Ted Kremenek writes: “Today is July 27 — and the last planned day to take source-breaking changes for Swift 3. It has been an incredible ride to this point, so let’s take stock of where we are.”

Accepted but not implemented reviews:

Ted continues:

“These are all changes the community has approved for Swift but did not make today’s cutoff. Some of these proposals have implementations actively underway. For those proposals already in active development — and near completion — I am okay with extending the deadline for those changes to Friday, July 29. Such changes need to be approved by the release manager (myself) and should be merged into master via a pull request. When creating the pull request, please assign it to me (tkremenek), and mention the pull request on the swift-dev mailing list as well with the SE number in the email title.

The rest of the unimplemented proposals do not make Swift 3. This leaves us with the question of what to do with them. These proposals represent the known and reviewed changes we want to make to Swift, but inevitably there will also be changes that we don’t even know about today that we will want to take into Swift that can impact core source stability. That said, we also have a very strong desire to maintain source compatibility with Swift 3 and Swift 4 as much as possible to provide some stability for which Swift users to build upon. The challenge of course is reconciling these diametrically opposing goals: maintaining source stability while having the ability to incorporate more core (and important) language changes that are possibly source-breaking.

The Swift team at Apple has reflected on this and decided what it “means” for Swift 3 to be source compatible with Swift 4 and later releases going forward. Our goal is to allow app developers to combine a mix of Swift modules (e.g., SwiftPM packages), where each module is known to compile with a specific version of the language (module A works with Swift 3, module B works with Swift 3.1, etc.), then combine those modules into a single binary. The key feature is that a module can be migrated from Swift 3 to 3.1 to 4 (and beyond) independently of its dependencies.

While the exact details of how we will accomplish this feat are still being discussed, here is a sketch of how this will likely work in the Swift 4 timeframe. The key enabler is a new compiler flag that indicates the language version to compile for (e.g., similar to the clang -std=c99 flag). The compiler flag will be provided by the build system you are using (e.g., Xcode, SwiftPM, etc.) on a per-module basis:

For language syntax/semantics, the compiler can use the language mode to properly implement the language version being used by a module.

For the Standard Library, additive and subtractive changes are easily handled (the former by just adding them, the later by using deprecation techniques). For semantics changes, things are much more complicated, and will need further study.

The great thing about this approach is that a single Swift 4 compiler is building all of the sources in an application. This allows us to roll out this approach before achieving full ABI stability — something that will be a goal for Swift 4, but is impractical to achieve for a Swift 3.x release. It also provides us a general framework in the future for handling source compatibility as Swift evolves.

To make this more concrete, suppose an application is written to use Swift 4, but uses packages via SwiftPM that are written using Swift 3. A single compiler would build both the app and the packages — thus ensuring that all the compiled sources are binary compatible. It would not be the case that a framework built with the Swift 3 compiler could be used by an app built using the Swift 4 compiler. That kind of library binary stability (ABI) will be a key goal of the Swift 4 release.

These constraints mentioned above will serve as scaffolding for Swift 4 development. Discussion about Swift 4 commences on Monday. Ahead of that, Chris Lattner plans to send out thoughts from the Core team on some of the known key goals (and non-goals) for the release. In the meantime, the focus over the next couple days should be taking stock of what has landed for Swift 3 and to see if any of the proposals mentioned above are close to being completed or are truly out of scope.

Thank you again to everyone for making Swift 3 such as fantastic release!”

Very last second Swift 3 reviews: big changes, little time

It’s crunch time. Several reviews are running concurrently for just a couple of days. All breaking changes must wrap up in the next week and Swift 4 design starts on 8/1.

Last Second Reviews

SE-0129: Package Manager Test Naming Conventions Accepted. Team writes:

There was relatively little feedback on the proposal but it had unanimous support, along with additional support for the future directions that are unblocked by the proposal with regard to allowing additional target types under the `Tests` convention directory.

SE-0131: Add AnyHashable to the standard library in review to 7/25. Accepted  “Currently the Objective-C type NSDictionary * is imported as [NSObject : AnyObject]. We used NSObject as the key type because it is the closest type (in spirit) to AnyObject that also conforms to Hashable. The aim of SE-0116 is to eliminate AnyObject from imported APIs, replacing it with Any. To import unannotated NSDictionaries we need an Any-like type that conforms to Hashable. Thus, unannotated NSDictionaries will be imported as [AnyHashable : Any]"

Team writes:

The feedback on this proposal was quite positive.  A few questions were raised, but were answered on-thread.  Thank you to Dmitri Gribenko for writing this proposal and driving this discussion forward.

SE-0132: Rationalizing Sequence end-operation names in review to 7/26 is Deferred from Swift 3. “Sequence and Collection offer many special operations which access or manipulate its first or last elements, but they are plagued by inconsistent naming which can make it difficult to find inverses or remember what the standard library offers. We propose that we standardize these names so they follow consistent, predictable patterns.” Team writes:

This is a very large proposal very late in the Swift 3 schedule. It has some clearly good pieces to it, but also many parts that are controversial with the community, and requires more design and iteration than time permits. It is best to defer this and make a change when we have something truly great, giving the benefit of proper time to design and evaluate the proposal.

Thank you to Brent Royal-Gordon and Dave Abrahams for driving this discussion. When the goals and parameters of Swift 4 are established, we should pick up this thread and see what makes sense to do here.

SE-0133: Rename flatten() to joined() in review to 7/26 Accepted. “This proposal renames flatten() to joined() (with no separator argument). It also adds a default separator of "" to the String-specific version of joined(separator:).” Team writes:

This proposal had significant positive community feedback for aligning common operation names, but raised questions about whether ‘flatten’ was term of art, and what it would mean for related operations like ‘flatMap’. The core team discussed both sides of this debate, and decided it is best to rename ‘flatten’ to ‘joined’, but keep ‘flatMap’ as it is, to preserve its term of art. The core team prefers that it remain a distinct overload of joined(separator:) to preserve performance. It also requests that the returned collection types (FlattenCollection and friends) be left as-is for now, since they are not names commonly directly referenced, and we’d like to keep the change minimal.

SE-0134: Rename two UTF8-related properties on String in review to 7/26 Accepted with Revision. “This proposal renames nulTerminatedUTF8 and nulTerminatedUTF8CString to enhance clarity and reduce mismatch between user expectations and the Swift programming language.” Team writes:

This proposal has two parts. The core team approves the first part: “Rename nulTerminatedUTF8CString to utf8CString”. This property is intended for use when interoperating with APIs that take C-style “char *” parameters.

For the second part, the proposal suggests “Rename nulTerminatedUTF8 to nullTerminatedUTF8.” The core team discussed this, looked at various uses of the API (among code bases publicly available on github) and came to the conclusion that it is best to just remove this property outright. The clients we found would be better served using the .utf8CString property.

Last Second Acceptances and Rejections

SE-0122: Use colons for subscript declarations is rejected. Team writes:

The feedback on this proposal from the community was overall divided with a slight bias towards reject.  Reasonable arguments were made on both sides: subscripts are definitely property-like in some ways, but they are also function-like in other ways.  Further, if we were aiming to align declaration syntax with use, arguably the parameter list should be enclosed in square brackets (but to be clear, we’re not going to do that). Overall, the core team agrees with the pervasive sentiment that this is not important enough to make a change for.

SE-0125: Remove NonObjectiveCBase and isUniquelyReferenced is accepted. Team writes:

This proposal had significant community feedback to help refine and improve its design, and Arnold has incorporated that into his v2 of the proposal.  The core team agrees the new revision is a good design.

SE-0127: Cleaning up stdlib Pointer and Buffer Routines is accepted with a modification.  Team writes:

This proposal got a significant amount of helpful feedback, which Charlie has already incorporated into the proposal.  The core team requests one additional minor change, which is to drop the addition of the ObjectIdentifier.unsafeAddress field.

SE-0128: Change failable UnicodeScalar initializers to failable is accepted. Team writes:

Feedback was universally positive, and the proposal is straight forward.

SE-0130: Replace repeating Character and UnicodeScalar forms of String.init is accepted. Team writes:

There was very little public discussion about this proposal, but the core team believes this eliminates a real ambiguity, while leaving doors open for future improved designs.


Wrapping up Swift 3

Of these four reviews, SE-0131 and SE-0134 are “gimmes” — that is, minor fixes that need relatively little discussion, offer obvious improvements, and can be evaluated on the spur of the moment. SE-0133 requires a little thought (“A concatenation of the elements of self“), but is also an easy up-or-down vote.

In contrast, SE-0132 is huge. It really deserves more time, attention, and consideration than the Apple-imposed deadline will allow. Brent‘s done a lot of work on perfecting this. If time permitted, it would have benefited from a few more weeks of discussion and revision.

Swift 3 Timeline

Swift 3’s  timeline concerns me. It will be ready for GM release along with Xcode 8 and iOS 10. I, personally, would prefer Swift 3 to be delayed six months or more to get it right the first time. As the planned major “breaking” release, the idea is twofold:

  • Offer incremental adoption by supporting Swift 2.3, which allows developers to build for the App Store using modern APIs in Swift 2.
  • Incorporate breaking code into Swift 3, so Swift 4 is ” as source compatible with Swift 3 as we can reasonably accomplish”. Further: “[S]ource breaking changes will be much more difficult to justify after Swift 3 is out the door, we’re prefer to roll them into Swift 3 where ever possible.”

With just a few days left before it becomes really really hard to fix fundamental design (although, I anticipate that dot-version changes to Swift 3 will be slightly more forgiving than Swift 3-to-Swift 4 changes), there’s been a big rush to find obvious flaws. For example, Open Issues Affecting Standard Library API Stability.

UpdateChris Lattner writes, “I strongly suspect there will be at least one 3.x release.”

On the other hand, August 1 is when the rush of additive proposals that have been back-burnered can come out and play. Swift 3 was all about getting the core language design fixed. Swift 4 is when new features can be considered. I’m hoping for things like method cascades, lenses, a better suite of functional programming tools, macros, strings-on-steroids, namespacing (without enums), and more.

See also: Announcement: Swift 3 Endgame and Swift 4 Kickoff

New Swift Evolution Reviews

Since so many new items have entered review after Wednesday, I’m adding an extra summary post. You can find the weekly full post here.

SE-0130: Replace repeating Character and UnicodeScalar forms of String.init in review to 7/24. “This proposal suggest replacing String initializers taking Character or UnicodeScalar as a repeating value by a more general initializer that takes a String as a repeating value. This is done to avoid the ambiguities in the current String API, which can be only resolved by explicit casting. It is also proposed to remove one of the String.append APIs to match these changes.”

SE-0129: Package Manager Test Naming Conventions in review to 7/26.  “Make the naming of tests be more predictable and more under the package author’s control. This is achieved in part by simplifying the naming conventions, and in part by reducing the number of differences between the conventions for the the Tests and the Sources top-level directories.”

SE-0128: Change failable UnicodeScalar initializers to failable in review to 7/24 “This proposal aims to change some (ones that are failable) UnicodeScalar initializers from non-failable to failable. i.e. in case a UnicodeScalar can not be constructed, nil is returned. Currently, when one passes an invalid value to the failable UnicodeScalar UInt32 initializer the swift stdlib crashes the program by calling _precondition. This is undesirable if one construct a unicode scalar from unknown input.”

SE-0127: Cleaning up stdlib Pointer and Buffer Routines in review to 7/24. “Update the API to match new API guidelines and remove redundant identifiers.”

SE-0126: Refactor Metatypes, repurpose T.self and Mirror in review to 7/24. “This proposal wants to revise metatypes T.Type, repurpose public T.self notation to return a new Type<T> type instance rather than a metatype, merge SE-0101 into Type<T>, rename the global function from SE-0096 to match the changes of this proposal and finally rename current Mirror type to introduce a new (lazy) Mirror type.”

SE-0117: Allow distinguishing between public access and public overridability revision 3 in review to 7/25 ” A public member will only be usable by other modules, but not overridable. An open member will be both usable and overridable. Similarly, a public class will only be usable by other modules, but not subclassable. An open class will be both usable and subclassable. This spirit of this proposal is to allow one to distinguish these cases while keeping them at the same level of support: it does not adversely affect code that is open, nor does it dissuade one from using open in their APIs. In fact, with this proposal, open APIs are syntactically lighter-weight than public ones.”

There’s a good roundup of (unhappy) opinion over at

Update: John McCall writes,

I’m resurrecting this thread to point out some minor revisions / clarifications that came up during implementation.

The first is that the accepted proposal contained “temporary” restrictions that required (1) open classes to subclass open classes and (2) open methods to override open methods.  (2) is actually inconsistent with our existing access-control rules about overrides: the overridden method doesn’t even have to be public.  Making a method open in a subclass shouldn’t force you to expose it in your superclass.  Therefore, we have lifted this restriction.  (1) is consistent with the access control rule on subclasses, so it has been conservatively kept; we’re still open to reconsidering this in the future.

The second is that the proposal wasn’t clear about how open interacts with initializers.  There are many things about our current class-initialization design that are unsatisfactory, but we are not going to fix them in Swift 3.  However, as a general matter, the clearest mental model for initializers is that every class provides its own, independent interface for constructing complete-objects / base-subobjects of that class.  The initializers in each class are formally distinct from the initializers in their subclasses, even when they happen to have the same signature; they are not in any real sense “overrides” (even if in some cases we do currently require the “override” keyword).  This is true even for required initializers, which merely state a requirement that all subclasses must provide a complete-object initializer with a particular signature, rather than expressing a real relationship between those initializers at each level.  Furthermore, it is understood that constructing an object of a subclass necessarily involves delegating to that subclass; subclasses must always be able to initialize their portions of constructed objects.  For all of these reasons, it is correct for initializers to not participate in open checking: they cannot be declared open, but correspondingly there are no restrictions on what initializers can be defined in a subclass, even if they have the same signature as an initializer from a superclass.

I have updated the proposal to reflect this.

Proterozoic-Oriented Programming: Swift Evolution

It’s Wednesday, so I’ll be filling these in as they pop up:


SE-0124: Int.init(ObjectIdentifier) and UInt.init(ObjectIdentifier) should have a bitPattern: label is accepted. Team writes:

There was very sparse commentary, and all of it was positive.  The core team believes this is an “obvious” proposal.

SE-0121: Remove Optional Comparison Operators is Accepted. Team writes:

Feedback has been universally positive from both the community and the core team, because it eliminates a surprising part of the Swift model at very little utility cost.

SE-0120: Revise partition Method Signature is Accepted. (Yay Nate!) Team writes:

There was very sparse commentary, and all of it was positive.  The one requested change from the discussion is to remove @discardableResult, which has already been made to the proposal.

SE-0116: Import Objective-C id as Swift Any type is Accepted. Team writes:

This proposal was very positively received by the community, and garnered a lot of feedback (which has already been incorporated into the proposal).  This proposal has significant implementation complexity, but the work to build it is nearing completion.  When this lands, there is some risk that we’ll need to revise the design in small ways due to unanticipated effects, but the core team believes it is the right overall design to aim for.

SE-0101: Reconfiguring sizeof and related functions into a unified MemoryLayout struct is Accepted. Team writes:

The proposal has been *accepted*, with a revision to change “MemoryLayout” into an enum with no cases.  The overall feedback was very positive.  The core team did discuss a proposal to move the generic type to each member, but felt that that would increase the verbosity of using the API (since T.self would be required) and would lead to possible confusion in the API (because it wouldn’t be clear whether you were asking for the size of a type, or the size of its metatype).


SE-0123: Disallow coercion to optionals in operator arguments is Rejected. Team writes:

The majority of the feedback on this proposal was opposed to it.  While the goal of the proposal is laudable, SE-0121 eliminated the most surprising problem that this proposal aimed to address, and the rest of it (notably the ?? operator) can be addressed in other ways in the Swift 3 timeframe.  The core team recommends that the ?? case be handled by having the compiler produce a warning when the left side of the ?? operator is implicitly promoted to optional.  In the post-Swift 3 timeframe, we can investigate other broader options for solving this problem more generally (e.g. a new parameter attribute).

SE-0119: Remove access modifiers from extensions is Rejected. Team writes:

The majority of the feedback on this proposal was opposed to it, because it eliminated the useful ability to apply access control to a batch of methods and properties.

Withdrawn For Revision

SE-0126: Refactor Metatypes, repurpose T.self and Mirror withdrawn for revision. Team writes:

The authors of SE-0126 have requested that we withdraw the proposal. The idea will be revised, return back to the “pitch” phase, and when that converges, SE-0126 will be revised.

Returned for Revision

SE-0117: Default classes to be non-subclassable publicly returned for a second revision. Team writes:

As with the first round of discussion, the community generated a large number of emails, exploring the various aspects of the proposal.  While many community members agree with the thrust of the proposal, a number of people are concerned with the boilerplate being introduced by the proposal, among other issues.  The core team spent over two and a half hours discussing this topic from first principles, and has come up with a similar-but-different approach that should reduce the boilerplate, while still accomplishing the primary aims of the proposal.  John McCall will be revising the proposal today and we’ll restart a short discussion period about it tomorrow.

In Review

I apologize for the formatting. Swift-Ev no longer lets me cut and paste from to add the summaries. I tried cutting and pasting the new format and it didn’t work very well.

SE-0130: Replace repeating Character and UnicodeScalar forms of String.init in review to 7/24. “This proposal suggest replacing String initializers taking Character or UnicodeScalar as a repeating value by a more general initializer that takes a String as a repeating value. This is done to avoid the ambiguities in the current String API, which can be only resolved by explicit casting. It is also proposed to remove one of the String.append APIs to match these changes.”

SE-0128: Change failable UnicodeScalar initializers to failable in review to 7/24 “This proposal aims to change some (ones that are failable) UnicodeScalar initializers from non-failable to failable. i.e. in case a UnicodeScalar can not be constructed, nil is returned. Currently, when one passes an invalid value to the failable UnicodeScalar UInt32 initializer the swift stdlib crashes the program by calling _precondition. This is undesirable if one construct a unicode scalar from unknown input.”

SE-0127: Cleaning up stdlib Pointer and Buffer Routines in review to 7/24. “Update the API to match new API guidelines and remove redundant identifiers.”

SE-0126: Refactor Metatypes, repurpose T.self and Mirror in review to 7/24. “This proposal wants to revise metatypes T.Type, repurpose public T.self notation to return a new Type<T> type instance rather than a metatype, merge SE-0101 into Type<T>, rename the global function from SE-0096 to match the changes of this proposal and finally rename current Mirror type to introduce a new (lazy) Mirror type.”

SE-0117: Allow distinguishing between public access and public overridability revision 3 in review to 7/25 ” A public member will only be usable by other modules, but not overridable. An open member will be both usable and overridable. Similarly, a public class will only be usable by other modules, but not subclassable. An open class will be both usable and subclassable. This spirit of this proposal is to allow one to distinguish these cases while keeping them at the same level of support: it does not adversely affect code that is open, nor does it dissuade one from using open in their APIs. In fact, with this proposal, open APIs are syntactically lighter-weight than public ones.”


to 7/22

Remove NonObjectiveCBase and isUniquelyReferenced

This replacement is as performant as the call to isUniquelyReferenced in cases where the compiler has static knowledge that the type of object is a native Swift class and dyamically has the same semantics for native swift classes. This change will remove surface API.


to 7/20

Int.init(ObjectIdentifier) and UInt.init(ObjectIdentifier) should have a bitPattern: label

This makes it clear at the use site that we interpret the value as a bit pattern


to 7/19

Disallow coercion to optionals in operator arguments

The convenience of coercing values to optionals is very nice in the context of normal function calls, but in the context of operators, it can lead to some strange and unexpected behavior.


to 7/24

Use colons for subscript declarations

Matches accessor declarations elsewhere in the language


to 7/19

Remove Optional Comparison Operators

Doesn’t work in current versions of Swift, because generics don’t support conditional conformances like extension Optional: Comparable where Wrapped: Comparable, so Optional is not actually Comparable.


to 7/19

Revise partition Method Signature

A more general partition algorithm using a unary (single-argument) predicate would be more flexible and generally useful.


to 7/19

Remove access modifiers from extensions

This proposal aims to fix access modifier inconsistency on extensions compared to other scope declarations types.


to 7/22

Default classes to be non-subclassable publicly

Not all classes make sense to subclass, and it takes real thought and design work to make a class subclassable well.


to 7/11

Import Objective-C id as Swift Any type

Objective-C’s id type is currently imported into Swift as AnyObject. This is the intuitive thing to do, but creates a growing tension between idiomatic Objective-C and Swift code.


to 7/19

Reconfiguring sizeof and related functions into a unified MemoryLayout struct

Discards the value-style standalone functions and combines the remaining items into a unified type.

Announcement: Swift 3 Endgame and Swift 4 Kickoff

Via Ted Kremenek

Hi everyone,

Swift 3 has shaped up to be a remarkable release — a product of the inspiration, ideas, and hard labor many people from across the Swift open source community. It is now time, however, to talk about the endgame for the release.

Here are the key points:

  • The last day to take planned source-breaking changes for Swift 3 is July 27.
  • On that day, there will likely be a set of approved-but-not-implemented proposals for Swift 3 — including proposals for source-breaking changes. Will have an open discussion on that day on the fate of those unimplemented proposals in the context of Swift 3 and future Swift releases.
  • Starting on August 1 we will open up discussion about Swift 4. Part of this discussion will likely be guided by important work that was deferred from Swift 3, as well as the a goal of achieving binary stability in Swift 4. Until then, however, discussion should remain focused on Swift 3.
  • Note that there is an intentional gap of a few days between the last planned day to take source-breaking changes for Swift 3 and when we start talking about Swift 4. The idea is to provide some time for the community to take stock of where things have ended up for Swift 3.
  • The final branching plan for Swift 3 development is to be determined, but the final convergence branch is likely to be cut from master around that date or shortly after. Part of it comes down to the discussion on July 27 on how to handle the remaining unimplemented proposals for Swift 3.
  • The final release date for Swift 3 is TBD, but essentially after July 27 the intent is that Swift 3 is in full convergence and not in active development.

With these dates in mind, I want to call attention to some approved-but-not-yet-implemented proposals that currently I have nobody on Apple’s Swift team able to tackle in the next couple weeks:

Some proposals — like SE-0075 — are things we can add at any time, but many of the others tie into the goal of achieving some degree of source-stability for Swift in Swift 3. I’m letting the community know that these proposals currently have no implementation traction in case there is interest in helping make them happen in time for Swift 3.

Related, I’d like to call out a special thanks to the community for getting implementation traction on SE-0095:

Currently there is a JIRA issue and pull request tracking work on implementing this proposal.

In addition to these language proposals, there is also an assortment of outstanding work for the Standard Library that would be great to do for Swift 3. There is a gist summarizing those tasks:

These tasks are broken down in relative order of difficulty, with a JIRA issue associated with each one of them. If a JIRA isssue is currently not assigned to anyone, please consider them fair game to tackle if you are interested. API changes that have currently not gone through the evolution process will still need an evolution proposal, even if they are listed in the gist. If you take on a specific task, please assign the JIRA issue to yourself so others know it is being tackled.

Thank you to everyone — and I mean everyone — who has contributed to making Swift 3 happen.


Like my posts? Consider buying a book. Content Update #1 is live.

Swift Developer’s Cookbook Content Update #1 is live

I’m pleased to announce that the Swift Developer’s Cookbook content update has gone live. My editor writes:

Hi Erica,
The Web Edition has been updated and is live (I just registered my book and checked it). To access the Web Edition, anyone who purchases the book can just register it at After doing so, the Web Edition will show up on the Account page.
You can feel free to post a blog entry, tweet, et cetera that the first update is live.

Pearson’s Content Update Program is brand new. It has experienced significant challenges over the past months: floods in Chennai followed by a massive downsizing at Pearson, which caught the CUP point people in the layoffs. With luck, further updates will not take so long. It’s a very weird time to be in the technical writing business.

If you’ve purchased a copy of the book from any vendor, you should be able to register it with InformIT and receive access to the refreshed material. If you have any difficulties, ping @InformIT on Twitter.

Holocene and heard: What’s up in Swift Evolution


SE-0089: Renaming String.init<T>(_: T) is accepted. Team writes:

The second review of SE-0089: “Renaming String.init<T>(_: T)” ran from June 4…7. The proposal is *accepted* for Swift 3.

The feedback from the community on this second round was light, which indicates that the extensive iteration on earlier rounds brought this to a good place. The core team discussed other possibilities for the parameter label (e.g. from: instead of describing:) but ended up agreeing that a more explicit “describing:” label is the best fit for this API.

SE-0106: Add a macOS Alias for the OSX Platform Configuration Test is accepted. Team writes:

The core team is proactively accepting SE-0106 “Add a macOS Alias for the OSX Platform Configuration Test” without a formal review, under the rationale that the proposal is “obvious” and probably should have been treated as a bug fix. Adding aliases for other uses of “OS X” in the language to use macOS are also proactively accepted.

SE-0095: Replace protocol<P1,P2> syntax with P1 & P2 syntax is accepted. “The current protocol<> construct, which defines an existential type consisting of zero or more protocols, should be replaced by an infix & type operator joining bare protocol type names.” Team writes:

This syntax has been extensively discussed by the community, and is a cornerstone of the “generalized existentials” work for future Swift releases.  The community was overall positive on the feature with a few subjective concerns about “&” being tightly associated with bitwise logical operations.  The core team believes this will not be contextually confusing since it appears in a type position, between two names that are obviously nominal types (e.g. they are capitalized).

I filed SR-1938 to track implementation of this work, this is a somewhat advanced starter project which would be a great place for someone to dive into the parsing logic in Swift.

SE-0104: Protocol-oriented integers is accepted with revisions. “This proposal cleans up Swifts integer APIs and makes them more useful for generic programming. The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators as free functions, thus polluting the overload set. Converting from one integer type to another is performed using the concept of the ‘maximum width integer’ (see MaxInt), which is an artificial limitation. Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations.” Team writes:

The feedback from the community was very positive and contributed a number of improvements to the design of the proposal.  The core team has accepted the proposal, subject to the following changes:

  • The “Integer” protocol should be renamed to “BinaryInteger” to be more accurate and avoid confusion between “Int” and “Integer”.
  • The “FloatingPoint” protocol should conform to the “Arithmetic” protocol.
  • Rename the “absoluteValue” property to “magnitude”, and sink it down to the “Arithmetic” protocol.
  • Eliminate the “AbsoluteValuable” protocol, since “abs” can now be defined in terms of “Arithmetic”.
  • Rename the “signBitIndex” property to “minimumSignedRepresentationBitWidth”.
  • Add a “popcount” property requirement to the “FixedWidthInteger” protocol.
  • Change the “countLeadingZeros()” member of concrete types to be a “leadingZeros” property on “FixedWidthInteger”.
  • Rename “func nthWord(n: Int) -> UInt” to “func word(at: Int) -> UInt”.
  • Rename the “and”, “or”, and “xor” members of “FixedWidthInteger” to “bitwiseAnd”, “bitwiseOr” and “bitwiseXor”.
  • Change “doubleWidthMultiply” to be a static member, and add a “doubleWidthDivide” member as its dual.  The latter will return both quotient and remainder of type “Self”. Both are to be added to the “FixedWidthInteger” protocol.

SE-0102: Remove @noreturn attribute and introduce an empty NoReturn type is accepted. “We should remove the rarely-used @noreturn function type attribute and instead express functions that don’t return in terms of a standard uninhabited type.” Team writes,

The feedback on the proposal was generally very positive from the community.  The only significant concern was from people who felt that merging the concept of “does not return” into the result type of the function conflates two concepts.  The core team feels that unifying these concepts overall reduces the surface area of the language by eliminating an obscure (but important) type system concept outright.

The other significant discussion was about the actual name for the “NoReturn” type.  The core team enjoyed the community idea of naming it “?” or ”?” but decided that the name lacked clarity.  Ultimately the core team agreed with the loud voice of the community that “Never” is the right name for this type.

SE-0103: Make non-escaping closures the default is accepted with a minor revision. “This proposal switches the default to be non-escaping and requires an @escaping annotation if a closure argument can escape the function body. Since the escaping case can be statically detected, this annotation can be added via an error with a fixit. Other annotations that have consequences for escape semantics (e.g., @autoclosure(escaping)) will be altered to make use of the new @escaping annotation.” Team writes:

Instead of a “asUnsafeEscapingClosure(_:)” function that removes the @escaping attribute, the core team prefers a function with this signature (roughly) like:

func withoutActuallyEscaping<ClosureType, ResultType>(_ closure: ClosureType, do: (fn : @escaping ClosureType) -> ResultType) -> ResultType { … }

This allows one to safely add the @escaping attribute in situations where a closure is known not to actually escape.

The key to this approach is that the “withoutActuallyEscaping” function can verify that the closure has not actually escaped when it completes, providing a safe model for locally adding the @escaping attribute when needed. The core team believes that the actual implementation of withoutActuallyEscaping will require some magic, but that it should be implementable.

Returned for Revision

SE-0077: Improved operator declarations is returned for revisions. The team writes:

On June 22, 2016, the core team decided to return the first version of this proposal for revision. The core design proposed is a clear win over the Swift 2 design, but feels that revisions are necessary for usability and consistency with the rest of the language:

  • The proposed associativity(left) and precedence(<) syntax for precedence group attributes doesn’t have a precedent elsewhere in Swift. Furthermore, it isn’t clear which relationship < and > correspond to in the precedencesyntax. The core team feels that it’s more in the character of Swift to use colon-separated “key-value” syntax, with associativitystrongerThan, and weakerThan keyword labels:
      precedencegroup Foo {
        associativity: left
        strongerThan: Bar
        weakerThan: Bas
  • If “stronger” and “weaker” relationships are both allowed, that would enable different code to express precedence relationships in different, potentially confusing ways. To promote consistency and clarity, the core team recommends the following restriction: Relationships between precedence groups defined within the same module must be expressedexclusively in terms of strongerThanweakerThan can only be used to extend the precedence graph relative to another module’s groups, subject to the transitivity constraints already described in the proposal. This enforces a consistent style internally within modules defining operators.
  • The proposal states that precedence groups live in a separate namespace from other declarations; however, this is unprecedented in Swift, and leads to significant implementation challenges. The core team recommends that precedence groups exist in the same namespace as all Swift declarations. It would be an error to reference a precedence group in value contexts.
  • Placing precedence groups in the standard namespace makes the question of naming conventions for precedencegroup declarations important. The core team feels that this is an important issue for the proposal to address. As a starting point, we recommend CamelCase with a -Precedence suffix, e.g. AdditivePrecedence. This is unfortunately redundant in the context of a precedencegroup declaration; however, precedencegroups should be rare in practice, and it adds clarity at the point of use in operator declarations in addition to avoiding naming collisions. The standard library team also requests time to review the proposed names of the standard precedence groups
  • This proposal quietly drops the assignment modifier that exists on operators today. This modifier had one important function–an operator marked assignment gets folded into an optional chain, allowing foo?.bar += 2 to work as foo?(.bar += 2) instead of (foo?.bar) += 2. In practice, all Swift operators currently marked assignment are at the Assignment precedence level, so the core team recommends making this optional chaining interaction a special feature of the Assignment precedence group.
  • This proposal also accidentally includes declarations of &&= and ||= operators, which do not exist in Swift today and should not be added as part of this proposal.

SE-0091: Improving operator requirements in protocols is returned for revision. “When a type conforms to a protocol that declares an operator as a requirement, that operator must be implemented as a global function defined outside of the conforming type. This can lead both to user confusion and to poor type checker performance since the global namespace is overcrowded with a large number of operator overloads. This proposal mitigates both of those issues by proposing that operators in protocols be declared statically (to change and clarify where the conforming type implements it) and use generic global trampoline operators (to reduce the global overload set that the type checker must search).” Team writes:

The review of “SE-0091: Improving operator requirements in protocols” ran from May 17…23.  While many people were positive about improving lookup of operators, several concerns about introduction of boilerplate were raised.  Tony and Doug have discussed it further and plan to revise and resubmit the proposal for another round of review.


SE-0101: Rename sizeof and related functions to comply with API Guidelines is returned for revision. “Upon accepting SE-0096, the core team renamed the proposed stdlib function from dynamicType() to type(of:) to better comply with Swift’s API guidelines. This proposal renames sizeofsizeofValuestrideofstrideofValuealign, and alignOf to emulate SE-0096’s example.” This one has a major alternative redesign being crafted. Team writes:

The thread discussing it has already turned towards new ways to express these ideas, so when that thread runs its course we’ll restart review of the revised proposal.


SE-0105: Removing Where Clauses from For-In Loops is rejected. “This proposal removes where clauses from for-in loops, where they are better expressed (and read) as guard conditions.” Expect a rejection on this very unpopular proposal but the team may adopt some of the alternatives considered for better language consistency. Team writes:

The vast majority of the community of the community prefers to keep this language feature, and the core team agrees.  Even though ‘where’ is a small bit of syntactic sugar, it improves the expressivity (therefore readability and maintainability) of important loops.

In Review

  • May 9…16 SE-0086: Drop NS Prefix in Swift Foundation “As part of Swift 3 API Naming and the introduction of Swift Core Libraries, we are dropping the NS prefix from key Foundation types in Swift.”
  • June 28 … July 4 SE-0107: UnsafeRawPointer API “Swift enforces type safe access to memory and follows strict aliasing rules. However, code that uses unsafe APIs or imported types can circumvent the language’s natural type safety.” This extensive redesign addresses many issues under the microscope.
  • June 28 … July 4 SE-0109: Remove the Boolean protocol “For legacy and historical reasons Swift has supported a protocol named Boolean for abstracting over different concrete Boolean types. This causes problems primarily because it is pointless and very confusing to newcomers to Swift: is quite different than Bool, but shows up right next to it in documentation and code completion. Once you know that it is something you don’t want, you constantly ignore it. Boolean values are simple enough that we don’t need a protocol to abstract over multiple concrete implementations.”
  • SE-0077 v2: Improved operator declarations in 2nd review to 7/4. (1st version) “Replace syntax of operator declaration, and replace numerical precedence with partial ordering of operators” However many reviews it takes, this is a good one to get right.
  • SE-0111: Remove type system significance of function argument labels in review to 7/4. “Swift’s type system should not allow function argument labels to be expressed as part of a function type. Removing this feature simplifies the type system. It also changes the way argument labels are treated to be consistent with how default arguments are treated; that is, tied to a declaration and not part of the type system”
  • SE-0110: Distinguish between single-tuple and multiple-argument function types in review to 7/4. “Swift’s type system should properly distinguish between functions that take one tuple argument, and functions that take multiple arguments. The current behavior violates the principle of least surprise and weakens type safety, and should be changed.”
  • SE-0108: Remove associated type inference in review to 7/4. “The main advantage of removing associated type witness inference is that it decreases the complexity of the type checker. Doing so removes the only aspect of Swift that depends upon global type inference. Simplifying the type checker makes it easier to improve the performance and correctness of the type checker code. Given that both are widely acknowledged issues with current versions of Swift, any opportunity for improvement should be carefully considered.”
  • SE-0112: Improved NSError Bridging in review to 7/4. “Swift’s error handling model interoperates directly with Cocoa’s NSError conventions. For example, an Objective-C method with an NSError** parameter will be imported as a throwing method. This proposal introduces new protocols and a different way of bridging Objective-C error code types into Swift, along with some conveniences for working with Cocoa errors.”
  • SE-0114: Updating Buffer “Value” Names to “Header” Names in review to 7/7. “This proposal updates parameters and generic type parameters from value names to header names for ManagedBuffer, ManagedProtoBuffer, and ManagedBufferPointer. All user-facing Swift APIs must go through Swift Evolution. While this is a trivial API change with an existing implementation, this formal proposal provides a paper trail as is normal and usual for this process.”
  • SE-0115: Rename Literal Syntax Protocols in review to 7/7. “This proposal renames the *LiteralConvertible protocols to ExpressibleAs*Literal.”


Nothing right now

Not Yet Scheduled

WWDC Thoughts

Screen Shot 2016-06-13 at 12.42.33 PM

This year, Apple offered a particularly subdued WWDC keynote introducing refreshes along all its product lines with few surprises or innovations. While the audience was politely enthusiastic, I’m not sure the tech press will be wowed.

I love the iOS playgrounds, although I think this is a better opportunity for institutions (say, Stanford) than little tutorial writers, and I got Sherlocked. Xcode introduces source editor extensions and there’s a Siri API using extensions.

Screen Shot 2016-06-13 at 1.06.26 PM

The download and upgrade process for Xcode, OS X (I mean macOS), and iOS has been amazing — just a dream process compared to previous years. Everything is operating smoothly from updating the conference schedule to providing bandwidth for desperate developer downloads. Fingers crossed this continues as well as it has started. I’m amazed at how clean the download site is, how simple the configuration profile approach is working (“Can I temporarily remove some large apps for space and re-install them later?” “Why YES!”). Big applause to whoever made these improvements.

Looking forward to the state of the union later today.



  • What’s new in Swift: Tues 11-11:40
  • Getting Started with Swift: Tues 2:40 – 3:40
  • What’s new in Foundation for Swift: Tues 5 – 5:40
  • What’s new in LLVM: Tues 6-6:40


  • Introducing Swift Playgrounds: Weds 12-1
  • Modern Best Practices: Weds 4-4:40
  • Swiftogether: Weds 7:15-8:45


  • Using and Extending Xcode’s Source Editor: Thus 6-6:40


  • Server-side with Swift Open Source: Fri 10-10:40
  • Swift Performance: Fri 12-1
  • Debugging Tips & Tricks: Fri: 2:40 – 3:40
  • Concurrent GCD w/ Swift: Fri 5-5:40
  • Protocol and Value Oriented Programing (in UIKit Apps): 5-5:40

Not Swift:

  • What’s new in Cocoa: Tues 12-1
  • What’s new in Cocoa Touch: Tues 2:40-3:40
  • Typography and Fonts: Weds 10-10:40
  • Speech Recognition API: Weds 5-5 (!?)
  • Intro to SiriKit: Weds 6-7
  • Extending Apps with SiriKit: Thus 2:40-3:40
  • What’s new in GameplayKit: Thus 10 – 10:40
  • Making Apps Adaptive: Thus 12-12:40, Fri 10-10:40
  • Proactive Suggestions: Fri: 2:40-3:40
  • Measurements and Units: Fri 5-5:40

Also: Some nice internationalization and accessibility sessions, a couple of worthy “adopting Metal” sessions, CloudKit best practices

iOS 10 Compatible Devices

I think this is probably the most reliable screenshot:

Screen Shot 2016-06-13 at 1.43.05 PM

There’s also this:

Screen Shot 2016-06-13 at 12.46.07 PM

and this:

Screen Shot 2016-06-13 at 1.46.51 PM

macOS Sierra Compatible Devices

Screen Shot 2016-06-13 at 1.59.25 PM