Goodbye and thank you OS X, hello and welcome macOS!
Sierra is here, also known as macOS 10.12. Apple's latest OS release, announced at the 2016 World Wide Developers Conference, offers the modern app developer more tools than ever with which to create engaging, productive, and entertaining apps for what an ever-increasing number of people deem the world's most advanced operating system.
Now that it's here, it seems it was a long time coming. Apple has renamed its desktop operating system to reflect its integral part in the Apple ecosystem, which comprises iOS, tvOS, watchOS, and finally macOS. This makes a lot of sense, since so much of what we know both as users and as developers from one platform is reflected in the others, sometimes very closely, sometimes adapted to differences in the hardware with which these platforms are used.
The cross-fertilization of Apple's platforms is rapidly increasing, giving new impetus to the desktop operating system that has in many ways taken a back seat to the mobile juggernaut that the iPhone and iPad represent. The massive adoption of mobile technologies has provided a spurt of innovation that Apple has begun to integrate seriously into what has become macOS. At the same time, decades of experience with macOS, then OS X, and now macOS have flowed into the mobile space as the processors in phones and other devices grow more powerful.
But although the name has changed, the OS is in every sense the next version of OS X, as the 10.12 version number makes clear. Visually, nothing has changed either;
About This Mac still shows the same small info window--only the mountain has changed:
This is really a great time to be an app developer. It is no exaggeration to describe what is happening across the globe as the digital revolution, and whether we're interested in productivity, entertainment, dissemination of information, or any one of scores of other development genres, we find ourselves on extremely fertile ground. It seems there are as many opportunities out there as there are souls ready to take on the challenges of creating the software that continues to drive progress at a breathtaking pace.
When approaching macOS as a developer, you will be able to make use of any and all experience you may have with programming for OS X, and if your background is in iOS and/or one of the other platforms, you will also discover the great extent to which you can leverage the knowledge and skills you have developed on those platforms. Indeed, much of the code you write for one platform will be directly usable in another, with little or no adaptation necessary.
If you are coming from a non-Apple background, I think it is safe to say you will find developing in Swift for macOS a rewarding expansion of your skills. Swift is a rich, flexible and expressive language, but not one that is hard to learn. It has, to some extent, a syntactic similarity to many modern object-oriented programming languages such as Python and Java (okay, modern in comparison to earlier popular successes such as Lisp and Fortran).
In this first chapter, we will look at the following topics:
- The Swift programming language
- Xcode and other development tools
- How this book is structured
- Some prerequisites for getting the most from this book
- What this book will do for you once you have read it
So, let's look at where this book is going to take you, and how it will get you there.
In just a little over two years, Swift has become one of the software development world's most talked-about programming languages, and is even the most forked repository on GitHub (but then, how many new languages have the power of a multinational like Apple behind them?). The language has undergone (and is still undergoing) incredibly rapid evolution, guided principally by Chris Lattner and the team at Apple, but also by the wider community, since it was open-sourced in December 2015, with proposals for language changes by non-Apple developers being included in the release of version 3.0. This radical departure from Apple's usually secretive product development strategy has meant that Swift has already benefitted from the experience and perspective of a great number of developers of mixed backgrounds (in every sense), with Apple itself saying that release 3.0 contains work by a total of three hundred and sixty-odd contributors.
But whether you refer to yourself as a software engineer, app developer, or hacker, there is substantially more to the job than writing Swift code inside Xcode. We will also be looking at interacting with bash shells in Terminal, dealing with files in XML format, data returned from the Web in JSON format, a little HTML, and the odd sprinkling of other languages, which may be used outside Xcode to good advantage.
We won't be going into a great amount of depth in these peripheral topics (if they can even be considered peripheral), but we will present what is essentially needed to get the job done, and give the reader an idea of the role they play in the larger picture. The interested reader will find no shortage of books and web resources with which to expand on the information presented here. There are also a number of articles available on the website that accompanies this book: http://grimshaw.de/macOS-book.
Much of this book, particularly the later chapters, will look at leveraging the considerable power of the Xcode-integrated development environment, in order to familiarize the reader with many aspects of development that go beyond code writing, to include debugging, performance measurement and improvement, working with source control within a team, and many others.
Software development is rarely a matter of using one single program, and we will be utilizing several tools other than Xcode to get the most out of the time we spend coding, compiling, and testing our work. You might be pleased to learn that none of these tools are going to cost you any money (although like any other tool, they come at the cost of a certain amount of time to be invested in order to reach a moderate level of proficiency). You might be even more pleased to learn that we will be covering this ground step by step, and no previous knowledge is assumed.
Despite the varied backgrounds that readers of this book are likely to have, we will make some broad assumptions about the level of skill and experience you bring with you. There are also some hardware requirements, though nothing you're unlikely to have already.
To be able to comfortably follow this book, you will need to have the following:
- A reasonably high level of familiarity with the macOS/OS X operating system and its day-to-day use, including trackpad gestures (in addition to mouse clicks, obviously), the file system as accessed through the Finder, and the general features of both Apple and third-party software.
- Some basic experience of programming using an object-oriented programming language such as Swift, Objective C, or Java.
- An Apple computer running at least macOS Sierra, with Xcode 8.0 or above already installed.
- Some chapters will require an Internet connection.
There are also a number of areas in which some experience will prove useful, though not necessarily essential, before we start, which are as follows:
- Using the Terminal app, and some knowledge of basic bash operation
- An understanding of the general principles of HTTP requests and responses, including JSON data
- Some knowledge of XML and HTML will also help
If any of those are completely new to you, you might want to find a little time to familiarize yourself with them. The website that accompanies this book contains introductions to all of the topics listed here, as well as several others is http://www.grimshaw.de/macOS-book.
Broadly speaking, the book can be thought of as consisting of three parts:
- The first few chapters will make sure that the basics have been covered, albeit very concisely. Less experienced readers may find it advisable to take these chapters slowly and possibly that some extra work is necessary to get up to speed.
- The second part concerns topics that are very much tied to programming for Apple devices in general, and macOS in particular, making use of native code provided by Apple through the Cocoa application programming interface. The chapters don't necessarily need to be read sequentially.
- The third part of the book moves beyond writing the code, to look at how to handle some of the challenges involved in producing robust and maintainable code in an up-to-date and practice-oriented context, and the tools that are available to make that easier.
In the beginning, there was Unix, developed by AT&T in the 1970s and initially intended for use inside the Bell system. Toward the end of that decade, the University of California, Berkeley, released a modified--and free--version of it, called Berkeley Software Distribution (BSD).
Apple released the Darwin operating system in 2000. It was derived from BSD and a number of other sources, including NextStep (which is why the Cocoa class names are generally prefixed with the letters NS), and contains the I/O Kit device driver API that saves you ever having to worry about getting keyboard or mouse input into the computer, and a million other things.
Info about Darwin is available at puredarwin.org, and if device drivers are your thing, Apple's I/O Kit documentation starts here: https://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/Introduction/Introduction.html.
Strictly speaking, macOS, like OS X before it, is a platform built on the Darwin operating system, although we generally think of it as being the OS itself (hardly surprising given the name), and it provides a collection of frameworks, a large group of which comprise Cocoa, which turn what is basically Unix into something that is basically much more than Unix.
All the shiny stuff, all those browser windows, sliders and buttons, movies, animations, sounds, file access (this list could get very long), what Cocoa does. Cocoa is what you use to create apps, mixed in with some logical organization and design. If devs were portrait painters, then Cocoa would be a cupboard full of brushes and tubes of paint.
Cocoa itself breaks down into different layers, including what Apple refers to as the Cocoa umbrella framework, made up of the AppKit, Foundation, and Core Data frameworks.
AppKit is part of the Cocoa application layer, and is made up of 125 classes and protocols, providing macOS with its user interface; event handling, drawing, menus, views, tables, text and fonts, printing, file system access, and so on are all to be found in AppKit.
Foundation provides us with the lower-level stuff such as data storage, arrays, dates, notifications and such, as well as abstract data classes that are not used directly, but from which many other classes are derived.
Core Data, as we will see in Chapter 9, Getting More from Interface Builder, provides us with a powerful framework for the management of persistent data.
The term Cocoa is very fluid; even at Apple it gets used in a more general sense to mean the whole range of frameworks, at many levels, available to you, the developer. And does it matter? I would argue that it does not. Whether a framework belongs to AppKit or Foundation, or some other layer, is going to make very little difference to your ability to craft engaging and useful software.
Cocoa is basically many, many lines of code, written by Apple's own developers, for use on its own platforms. How many lines? I'd love to know, too, but I don't see Cupertino releasing that kind of information anytime soon. Suffice to say, drawing a window on a screen starting with nothing but 1s and 0s is far from trivial, and you should be glad you don't need to do it yourself. Apple has done it for you, millions of times. Despite the fact that drawing such a window involves as much logic as a small Xcode project itself, all you need to do is write a couple of lines of code and there it is, ready for you to add the sexy stuff. All the detail, all that boilerplate, has been abstracted away for you. And the same goes for countless other blocks of repetitive but superbly tweaked code that you will likely never see (and quite possibly never think about again).
All you need to do to make use of this mountain of tested, optimized, and field-hardened code is issue the correct instructions to the libraries, which means knowing the Cocoa API. It's a very large API, to be sure. And nobody--nobody at all, not even at Apple--knows all of it. Some parts you may have learned inside and out already; others you certainly will learn. But for as long as you write Cocoa apps, you will be looking things up in Apple's documentation, or searching Stack Overflow and other developer forums for help and advice.
In case you don't know it (yet), Stack Overflow frequently abbreviated to SO, is one of the most valuable resources on the Web. You can search and read the site without membership, but once you're signed up, you can post questions and, indeed, answer them. The rules are quite strict, and the levels of discipline and respect are very high. Seriously, if you're into development, you'll love SO. It can be found here: http://stackoverflow.com.
The various Cocoa frameworks presented in the second section of this book are those that are likely to be of relevance to a majority of readers. A firm grounding in these topics will provide you with a solid fundament on which to mold Apple's huge repository of code into apps of a professional standard, and with experience of one set of frameworks, you'll find it ever easier to get to grips with new ones, even to the extent that you will often be able to make an educated guess rather than consulting the docs. The Cocoa APIs have been updated to work more expressively with Swift, which in turn means it becomes easier to recognize the patterns being used in the frameworks you use, as the interface between Cocoa and the Swift language itself become more consistent.
The third part of the book will cover topics that concern any desktop application developer, but here they are dealt with in the context of programming Cocoa apps for macOS.
Some of these will seem more appealing than others. There are many topics in the early stages of learning to program that are (or perhaps just seem to be) less important and/or exciting, such as just writing a few pages full of code and hitting the
Run button; but these things later become an essential and rewarding part of what we do as developers. As one moves from working on relatively small and simple projects, usually as a sole coder, to working on larger, more complex, and longer-term projects, frequently as part of a team of both devs and management staff, there is a profound change in priorities, as code clarity, code re-use, integration, documentation, and communication become major aspects of our work.
There are also fascinating challenges around dealing with some of the unpredictable aspects of software that needs to integrate itself successfully with a digital universe lying outside our app and beyond our control, particularly with regard to the Internet, as our code will need to deal robustly, efficiently, and gracefully with whatever comes back at it across the network.
Producing high-quality code, while working quickly and communicating effectively, is partly a matter of experience and partly a matter of knowing what tools are available to make the best use of the hours you spend coding, and which techniques to choose when designing the internal workings of your app.
These chapters will look at the challenges posed by asynchronous programming, error handling, debugging, and many other areas that are an indispensable part of producing software in a professional environment: on time, on budget, maintainable code. Which is basically what the industry needs from you.
And for which you will be handsomely paid. Just saying.
This brings us quite nicely to the goals of this book.
Well, in a general sense, its goal is to help you reach yours, of course. But how exactly are we going to do that?
The focus of this book is very much on real-world programming skills and best practices, with a clear preference for techniques that provide solid, maintainable code over a long app lifetime, as opposed to the latest Thing from the developer conferences. Similarly, we will concentrate more on the functional interior of the code rather than short-lived user-interface design trends that will be of little interest a year from now.
There is also a strong emphasis on developing the skills that a developer will need when working in the industry, within a team that may include other developers, including those working on different platforms, as well as graphic artists, technical leads, project and product managers, system administrators and back-end developers, and any number of other roles with which it is necessary to communicate with clarity and accuracy. These people will have their own corners of the business to attend to, to which you will frequently have to adapt your work, making it all the more important that you have a number of tools at your disposal to deal with rapidly changing requirements and priorities.
Frequently, it is necessary to include third-party frameworks and libraries, often ones that you would not choose yourself: maybe because the team has been using them within a project already; maybe because a client has requested the addition of an analytics engine to an app, or to add functionality to an app not available natively. These are perhaps the most common reasons, but they are not the only ones, and an ability to integrate these resources into your work is an essential part of modern app development, and one that is only likely to increase with time.
Professional coding means writing clear code, adhering where appropriate (which means most of the time) to established practices. We will prefer simplicity over cleverness every time, and hopefully this is a habit you will develop yourself.
Write every line of code for somebody else. That may mean someone else in your team, or it might mean your successor when you move on. It will frequently mean yourself in a year's time--which is when you'll be most glad you wrote logical, well-structured code.
A huge part of coding wisely means knowing which techniques to deploy, and which are better left out, in any given situation. It means learning to strike the right balance between clarity and the inevitable complexity that results from the growth of a project over time.
You will also learn to deal with version control safely, an essential part of working on larger projects, even as a sole developer.
Debugging your code is an essential part of programming, and we will look at the tools available to you in Xcode to make these tasks easier, faster, and safer. Fixing bugs can become a major part of your work, and your skills in this area will contribute greatly to your ability to deliver reliable code.
Finally, we will not shy away from references to resources beyond this book. The time is long gone when a developer can be expected to know every detail of a language or platform, and knowing where to search for documentation and help is an indispensable part of our work as developers. It has been said that a good developer spends two thirds of the time reading and one third coding. Although that should perhaps be taken with a pinch of salt, if only because it overlooks writing documentation, testing, and talking to clients, managers, and team members, it nevertheless makes clear that writing code is not only not everything, it's not even most of it.
Our highest priority is to impart knowledge that will be immediately and enduringly useful to you as a developer. That may seem like stating the obvious, but you will notice that the content of this book does not necessarily reflect the buzz and hype around the blogosphere's latest shiny new toys. It is true that even the oldest, best-tested tools were new once, but it is not our intention here to get lost in the esoteric delights of functional programming, protocol-oriented programming, reactive programming, or whatever else is the subject of heated debate at the time of writing.
That is not to say that such topics are somehow not thrilling, valuable, and thought-provoking. They most definitely are, but they are not within the scope of this book. However, the website is not limited in size, so we'll see what we can do.
Also not covered here is the migration and adaptation of Swift 2 code to Swift 3. There will doubtless be any number of articles out there covering this, but for the purposes of this book, we will treat Swift 3 as the only version of interest. And although it's an important topic, moving from Objective C to Swift is beyond the scope of this book.
Finally, we will not cover unit tests and integration testing. This field is a wide one, space here is limited, and the reader is encouraged to find resources that can do justice to both the topic itself, and the wide range of opinions surrounding it.
None of this is going to involve quantum leaps of comprehension. Assuming you understand the concepts summarized in the first few chapters (and we will make that assumption), this book will guide you, step by step, from a position of being able to code adequately to a position of being able to code well.
You will not only write better code, you'll write faster; you will be able to get across new frameworks more quickly; you'll soak up more of what you read on the Web and elsewhere; you'll be able to communicate your thoughts clearly to work colleagues and clients.
And I hope, very much, that you'll continue to feel that feeling of accomplishment you felt the first time you coded up
Hello World in whatever language it was at the time. It's that spark that will enable you to code not only well, but brilliantly, if you stick with it.
The next chapter will provide a rapid-but-thorough review of the basics of the language's core features and syntax, assuming a basic familiarity with object-oriented programming, but no advanced knowledge of Swift's previous incarnations. So, without further ado, let us take a rapid tour of the basics of Swift 3.0.