Server-Side Swift (Paul Hudson) (Z-Library)
Author: Paul Hudson
其他
Learn to make web apps with real-world Swift projects
📄 File Format:
PDF
💾 File Size:
10.9 MB
50
Views
0
Downloads
0.00
Total Donations
📄 Text Preview (First 20 pages)
ℹ️
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
📄 Page
1
Paul Hudson HACKING WITH SWIFT COMPLETE TUTORIAL COURSE Learn to make web apps with real-world Swift projects
📄 Page
2
Contents Preface 6 About this book Why does Kitura exist? A note for existing Swift developers Configuring your machine Introduction: Swift for Complete Beginners 21 How to install Xcode and create a playground Variables and constants Types of Data Operators String interpolation Arrays Dictionaries Conditional statements Loops Switch case Functions Optionals Optional chaining Enumerations Structs Classes Properties Static properties and methods Access control Polymorphism and typecasting Closures Wrap up Million Hairs 101 Setting up Swift packages explained Starting a server Routing user requests Writing HTML Matching custom routes Making it look good www.hackingwithswift.com 2
📄 Page
3
Wrap up CouchDB Poll 139 Setting up CouchDB from scratch Designing a JSON API Bringing CouchDB and Kitura together Creating CouchDB documents Casting a vote Wrap up Routing 178 Setting up Chaining routes Reading user data Routing regular expressions Wrap up Swift Fan Club 191 Setting up Listing forums Querying with a key Closures within closures Users and sessions Posting messages and replies Wrap up Meme Machine 237 Setting up Reading files from disk Multi-part form encoding Wrap up Templates 251 Setting up Recap on the basics Filters and tags Wrap up Barkr 265 Setting up www.hackingwithswift.com 3
📄 Page
4
An SQL primer Integrating MySQL with Kitura Generating tokens Reading insert IDs Over to you: fuzzy search Wrap up ASCII art 300 Setting up Updating pages interactively Reading remote images Wrap up Databases 316 Setting up Indexing for performance Normalization for efficiency Referential integrity for organization Transactions for consistency Default values for safety Wrap up Instant Coder 333 Setting up Say hello with GitHub Rendering the basic UI Creating new accounts Routing to success Creating new projects Finding places to work Wrap up AppleFanatic 370 Setting up Bootstrapping our servers Fetching stories from a database IDs, slugs, and Markdown Stories and errors Browsing by category Creating an admin section Wrap up www.hackingwithswift.com 4
📄 Page
5
Testing 422 Setting up Bootstrapping XCTest Testing our routes Wrap up www.hackingwithswift.com 5
📄 Page
6
Preface www.hackingwithswift.com 6
📄 Page
7
About this book The Server-Side Swift tutorial series is designed to make it easy for beginners to get started building web apps and websites using the Swift programming language. My teaching method skips out a lot of theory. It skips out the smart techniques that transform 20 lines of easy-to-understand code into 1 line of near-magic. It ignores coding conventions by the dozen. And perhaps later on, once you've finished, you'll want to go back and learn all the theory I so blithely walked past. But let me tell you this: the problem with learning theory by itself is that your brain doesn't really have any interest in remembering stuff just for the sake of it. You see, here you'll be learning to code on a Need To Know basis. Nearly everything you learn from me will have a direct, practical application to something we're working on. That way, your brain can see exactly why a certain technique is helpful and you can start using it straight away. This book has been written on the back of my personal motto: "Programming is an art. Don't spend all your time sharpening your pencil when you should be drawing." We'll be doing some "sharpening" but a heck of a lot more "drawing" – if that doesn't suit your way of learning, you should exit now. The three golden rules The series is crafted around a few basic tenets, and it's important you understand them before continuing: 1. Follow the series: The tutorials are designed to be used in order, starting at the beginning and working through to the end. The reason for this is that concepts are introduced sequentially on a need-to-know basis – you only learn about something when you really have to in order to make the project work. 2. Don't skip the technique projects: The tutorials follow a sequence that places a technique project after every two app projects. That is, you develop two apps then we focus on a particular component to help make your code better. The apps are standalone projects that you can go on to develop as you wish, whereas the technique tutorials will often be used to improve or prepare you for other projects. www.hackingwithswift.com 7
📄 Page
8
3. Get ready to hack: This is not designed to be the one-stop learning solution for all your Swift needs. The goal of each project is to reach the end with as little complication as possible, while learning one or more things along the way. I can't re-iterate that last point enough. What I have found time and time again is that any tutorial, no matter how carefully written or what audience it's aimed at, will fail to fit the needs of many possible readers. And these people get angry, saying how the tutorial is wrong, how the tutorial is lame, how their tutorial would be much better if only they had the time to write it, and so on. Over the last 12 years of writing, I have learned to ignore minority whinging and move on, because what matters is that this tutorial is useful to you. You'd be surprised by how many people think the path to success is through reading books, attending classes or, well, doing pretty much anything except sitting down in front of a computer and typing. Not me. I believe the best way to learn something is to try to do it yourself and see how it goes. Sure, going to classes might re-enforce what you've learned, or it might teach you some time- saving techniques, but ultimately I've met too many people with computing degrees who stumble when asked to write simple programs. Don't believe me? Try doing a Google search for "fizz buzz test", and you'll be surprised too. So, dive in, make things, and please, please, please have fun – because if you're not enjoying yourself, Swift coding probably isn't for you. If you spot any errors in this book, either typos or technical mistakes, please do let me know so I can correct them as soon as possible. The best way to get in touch is on Twitter @twostraws, but you can also email paul@hackingwithswift.com. Xcode, Swift and Kitura I'm not going to talk much, because I want to get straight into coding. However, there are some points you do need to know: www.hackingwithswift.com 8
📄 Page
9
• I’ve written these tutorials using Xcode 8.1, which is available for free from the Mac App Store. If you’re using an earlier version of Xcode you should upgrade before continuing otherwise you may encounter bugs. • If you’re using Linux or considering using Linux, please read the introductory chapter “A note on Linux”. • Swift is a relatively new language, and is evolving quickly. Every new release of Xcode seems to change something or other, and often that means code that used to work now no longer does. At the time of writing, Swift is mature enough that the changes are relatively minor, so hopefully you can make them yourself. If not, check to see if there's an update of the project files on hackingwithswift.com. • These projects are designed to work with Kitura 1.0 or later. Please upgrade your system otherwise you’ll find this book very confusing indeed! Important note: if any bugs are found in the project files, or if Swift updates come out that force syntax changes, I'm going to be updating this book as needed. You should follow me on Twitter @twostraws if you want to be notified of updates. I'm also happy to answer questions on Twitter if you encounter problems, so please feel free to get in touch! Swift, the Swift logo, Xcode, Instruments, Cocoa Touch, Touch ID, AirDrop, iBeacon, iMessage, iPhone, iPad, Safari, App Store, Mac, and macOS are trademarks of Apple Inc., registered in the U.S. and other countries. Server-Side Swift is copyright Paul Hudson. All rights reserved. No part of this book or corresponding materials (such as text, images, or source code) may be reproduced or distributed by any means without prior written permission of the copyright owner. Acknowledgements I'd like to thank Ankit Aggarwal for his invaluable help and advice with the Swift package manager. It's a fast-developing part of our ecosystem, but Ankit is doing a great job documenting all the changes and supporting everyone who has questions. I'm also grateful to Kyle Fuller for being so responsive with answers, features, and fixes to his www.hackingwithswift.com 9
📄 Page
10
Stencil template engine. His work made my life a great deal easier, and I look forward to seeing where Stencil goes next! Dedication This book is dedicated to IBM's Kitura team, who have patiently answered my many questions on their Slack channel. Chris Bailey, Shmuel Kallner, Youming Lin, Ian Partridge, and others – thank you! www.hackingwithswift.com 10
📄 Page
11
Why does Kitura exist? It doesn’t matter whether you’ve been using iOS, macOS, watchOS, or tvOS – they are all very different to working on the server. Taking iOS as an example, you’re already used to the idea that apps are built using multiple layers. Here are some of them: 1. The Swift programming language provides us with basic syntax and functionality like func, var, as well as closures, classes, and so on. 2. The Swift standard library is a large body of code that provides basic data types and methods: what is an Int? How do you sort an Int array? What does the print() function do? 3. Foundation is Apple’s framework for providing extended data types, such as Date, Data, and UUID. 4. Grand Central Dispatch (GCD or “libdispatch”) is a low-level framework for letting us add concurrency without much of the pain. (That is, the ability to run more than one piece of code at a time.) 5. Core Graphics, Core Image, Core Animation, Core Data, Core Text, and many other low-level frameworks provide specific services we can draw on to solve problems. 6. UIKit is Apple’s framework for creating interactive user interfaces for iOS. These layers build on top of each other: if you remove any of the lower layers, UIKit would either not exist or be dramatically worse off. Together, layers 3 through 6 are sometimes (erroneously) called “Cocoa Touch” on iOS or “Cocoa” on macOS, but it’s a helpful term because it just means “our fundamental app building blocks.” That list is far from exhaustive, but it gives us enough for me to describe the most important thing you need to know: server-side Swift is Swift without most of Apple’s frameworks. Yes, you still get the Swift language and the standard library, but you get none of the “Core” layer (Core Graphics and so on), you get none of the UIKit, AppKit, or WatchKit frameworks, and Foundation is incomplete. Yes, you read that right: Foundation is incomplete. This means many methods will fail because they haven’t been written yet, other methods might work for some specific code paths, and other methods are implemented fully. On the bright side, you do get GCD, which works just the same on the server as it does on Apple’s platforms. www.hackingwithswift.com 11
📄 Page
12
the same on the server as it does on Apple’s platforms. So, with large parts of Foundation missing, plus all “Core” and “Kit” frameworks completely absent, server-side Swift is significantly simpler. If you followed my books Hacking with Swift or Hacking with macOS, you’ll know that most of the learning is about figuring out how UIKit works. Not so with server-side Swift: because it’s significantly simpler, you can spend more time focusing on how to build projects with what you know rather than always having to learn new things. Because Apple’s framework footprint is significantly smaller, third-party libraries step in to fill the gaps. That’s where Kitura comes in: it’s a framework developed by IBM to provide the tools we need to build web apps and websites. There are four main web frameworks at the time of writing, but I chose Kitura for this book for a number of reasons: 1. It’s extremely fast, coming 1st or 2nd in most benchmarks. 2. It was introduced by Apple at WWDC 2016, as part of their partnership with IBM to bring Swift to the enterprise. 3. It’s being backed with considerable investment by IBM, so it’s picking up pace extremely quickly. 4. It’s similar to Express.js, a hugely popular JavaScript framework, which means many existing web developers can pick up Kitura easily. Each of those reasons is compelling by itself, but there’s another important reason that really shapes the way you work with server-side Swift: Kitura is highly modular. This means you use the basics of Kitura to handling fundamental functionality, but after that you can pick and choose components from elsewhere to solve whatever problems you have. In this book, I’ll be using Kitura for as much as possible, because it comes with a lot of the functionality we need to build great web apps. However, I’m not an API zealot: when alternatives such as Vapor do something better, we’ll be using that. Remember, Kitura is modular, so you can plug other components in as needed – this is by design, and means we can all use what works best rather than being constrained to one specific approach. So, although we lose large parts of Foundation and all the higher frameworks, many gaps are filled by frameworks such as Kitura. And when Kitura alone isn’t enough, we’ll be drawing on other frameworks such as Vapor – as long as it’s Swift, it’s available for us to draw on. www.hackingwithswift.com 12
📄 Page
13
A note for existing Swift developers If you’ve written Swift for one of Apple’s four platforms, moving to server-side Swift can be a bit of a shock. As I’ve said, it’s simpler, but “simple” and “easy” aren’t the same thing. Sure, server-side Swift doesn’t have UIKit, AppKit, Core Graphics, and so on – massive APIs that take months to learn and years to master. But in their place, you’ll find a huge range of things that web developers take for granted: sessions, templates, forms, routing, HTTP methods, and more. Databases alone are so big, and so utterly fundamental to any website of note, that there are 1000-page books dedicated to them. You'll also find that server-side Swift develops significantly faster than iOS, macOS, or other Apple platforms. Not only does Apple create yearly releases, but they also have extremely extended deprecation periods – you can rely on deprecated APIs to carry on working for three to five years before they are finally removed entirely. Not so on on the server: often releases happen every week, and it's common to see breaking changes come and go rather than have a gentle deprecation period. Because many of these things are likely to be new to you, I want to place a message of encouragement early on in this book: if you find yourself thinking that all this web stuff is hard, you’re right – it is hard. But I’ve done my best to explain everything slowly, carefully, clearly, and thoroughly, so I hope you’re able to stick with it. If (when!) you find that APIs have been changed between me writing this book and you reading it, email me at paul@hackingwithswift.com and I'll do my best to help. The complexity of server-side Swift is such that this book is a little different from my others. More specifically, although I still try to teach things in a linear fashion, the projects aren't strictly graded by difficulty. Even more specifically, I've inserted two easier projects part-way through the series to help break up the flow, because without them it can just seem like an overwhelming amount of hard work. Trust me, by the time you reach project 5 (the first of the easier projects) you'll be more than ready for a break! www.hackingwithswift.com 13
📄 Page
14
Configuring your machine Working with server-side Swift is quite different from client-side Swift such as iOS and macOS for one large reason: macOS is very rarely used on servers. It’s possible to use macOS for your web server, but this usually only happens if someone desperately needs macOS features such as Xcode running on a remote server. Instead, servers are primarily the domain of Linux, an open-source operating system that has some things – but not many! – in common with macOS. When Swift was open sourced in December 2015, Apple shipped Swift and the standard library for macOS and Linux. They also shipped a limited version of Foundation, which has slowly been improving over subsequent months. IBM’s Kitura framework, along with the various Kitura-related components that IBM provides, are also designed to work on macOS and Linux, so as long as you stay within the boundaries of the Swift standard library, the open-source Foundation framework and Kitura, your code should work identically on both macOS and Linux. Now, “should” is a complex word that really means “in theory this does what I think it does, but in practice I bet it doesn’t.” The problem is two-fold: 1. Foundation on macOS is the original Apple version, which is feature-complete and battle-tested. Foundation on Linux is Apple’s open-source reimplementation, which is missing many features. 2. macOS uses a case-insensitive filesystem by default, whereas Linux uses a case- sensitive filesystem. This means Linux is less forgiving about small filename mistakes. If you code on macOS and deploy to Linux, you might hit filesystem problems due to case-sensitivity. Now for the complicated part. If you’re already an iOS or macOS developer, you’re used to the concept that your entire environment is dictated by your Xcode version number. Which SDKs you have, what Swift compiler version you have, how your storyboard editor looks, and so forth are all decided by your Xcode version. Not so in server-side Swift. You might code on macOS and deploy to Rackspace Cloud www.hackingwithswift.com 14
📄 Page
15
running Ubuntu 16.04, or you might code on Linux and deploy to IBM Bluemix running Ubuntu 14.04. Each of those environments are very different, and although Swift itself will be the same everywhere the environment it runs in will vary. No matter what you choose, ultimately your code needs to run on Linux. That in turn means it needs to avoid using the incomplete parts of Foundation, and requires you to be careful about case sensitivity in filenames. The best way to ensure you’re working correctly is to build and run your code on Linux every step of the way. You can code on macOS if you want, it doesn’t really matter – but you do need to build and run on Linux, to ensure what you’ve written can be deployed to a real server. If you aren’t already running Linux as your desktop operating system, there are four options you can take: 1. Use virtualization software such as VMware Fusion or Parallels. This lets you install a full version of Ubuntu Linux locally, for coding and testing. 2. Set up a cloud server using something like Digital Ocean. This costs about $5 per month, or less if you pause the instance when you don’t need it. 3. Use Docker, which is a bit like an invisible virtual machine running Linux on macOS. (Note: it still reads and writes from your macOS hard disk, so it does not solve the case-sensitivity problem.) 4. Pretend Linux doesn’t exist, and build and run everything on macOS. Of the four options, #3 is by far the most popular. Docker is a free program you can install, it lets you create Linux containers that are pre-configured for running Kitura, and it blurs the lines between macOS and Linux because you can write your code on macOS and run it inside the Linux instance. Before you can continue with this book, you need to decide which of the four options you want. You can’t not choose – you need to pick one. If you’re not sure, go with #3. Later projects require you to install database software, and this is significantly easier if you use Docker. Trust me on this: although it’s a little harder to get started, I strongly recommend you choose Docker. www.hackingwithswift.com 15
📄 Page
16
If you chose #1 or #2, please go ahead and install Ubuntu now, either locally or in your preferred cloud provider. When installation has finished run these commands: sudo apt-get update sudo apt-get install clang libicu-dev libcurl4-openssl-dev libssl-dev Finally, download and extract the correct Swift version for your Ubuntu version from https:// swift.org/download/#releases. If you chose #4, please make sure you have Xcode 8.1 installed from the Mac App Store. That’s it. Yes, #4 is easy, but trust me: it’s extremely easy to create problems for yourself down the line, and you’ll need to troubleshoot them yourself. If you chose #3, go to https://docs.docker.com/docker-for-mac/ and click “Get Docker for Mac (stable)” to download the latest version of Docker. When the DMG has downloaded, double- click it to open, then drag it to Applications. Once it has finished copying, browse to your Applications folder in Finder and double-click Docker to start it – you’ll be asked to enter your admin password in order to complete setup. A brief Docker primer Rather than repeat instructions for Docker in every project, I want to give them just once so you can refer back here as needed. To make things simple, I’ve crafted one Docker command that does everything you need to create, start, and gain access to an environment where you can run your projects. Once you’ve installed the Docker app and started it, you should see a whale icon in your Mac’s status bar - that shows the Docker virtualization system is running. Open a terminal, then run these commands to create a directory on your desktop where you’ll store all your server projects: cd Desktop mkdir server cd server www.hackingwithswift.com 16
📄 Page
17
Note: It’s possible your terminal starts you at a different location. If you see “~” in there then the commands above are correct, but if you see “~/Desktop” or similar then you’re already in your Desktop directory and can skip the first command. That creates a directory called “server” and changes into it so that it’s the current working directory. Now run this command: docker run -itv $(pwd):/projects --name projects -w /projects - p 8089:8089 -p 8090:8090 -p 5984:5984 twostraws/server-side- swift /bin/bash Yes, that’s quite a lot, but it’s because I’ve tried to cram everything into one! What the command does is: • Tell Docker that we want to run a command in a new container – an isolated virtual machine that will run Linux. • Request an interactive terminal (“it”), which is something we can type commands using /bin/bash – the default Linux terminal. • Attaches a volume (“v”), which means “/projects” inside the container will refer to the current working directory. • Tells Docker that we want to map our network port 8089 to the container’s port 8089, map our network port 8090 to the container’s port 8090, and our network port 5984 to the container’s port 5984. More on that in a moment! • Names the container “projects” (“--name projects”) so we can refer to it more easily. • Sets the working directory to be “/projects” so we start ready to go. • Tells Docker to build the container using “twostraws/server-side-swift”, which is a pre- configured Docker container that I’ve designed to make this book easy to follow. It contains everything we need to get started. When you run that command Docker will need to download all the components required to make the container work, including Ubuntu itself as well as my customizations. If you’re curious, my customized version updates all the software, adds Swift, Curl, CouchDB, and www.hackingwithswift.com 17
📄 Page
18
MySQL, ready for all the projects in this book, and is based on IBM’s own Docker container. After a few minutes you’ll find yourself looking at a terminal prompt like this: root@f2429f0045db:/projects# That means installation has now completed: you’re now in the “projects” directory inside the container. This is mapped to the current working directory, so if you create any files here you’re really creating files in the “server” directory on your Mac’s desktop, and if you change any files in macOS those changes will be reflected in the Docker container. Using one Docker container for all projects isn’t the preferred way of working, but it’s fine for beginners. When you become more experienced you’ll start creating individual containers for each project, and indeed each part of a project, but the single-container approach makes life easier for now. The command you ran bridged the network ports 8089, 8090, and 5984 inside the container to ports 8089, 8090, and 5984 on your Mac. What this means is that if you try access any of those ports on your Mac, you get seamlessly transferred to the container. We did this because the Kitura server runs on port 8090 by default, so it allows us to test content directly from a web browser on your Mac. Port 5984 isn’t used until project two, and 8089 isn’t used until project eleven, but we need to configure both them and 8090 now, when creating the container. You’ll see this in action soon enough! Before we’re done, I want to show you a few important Docker commands to help you get into and out of your container. Right now, you see a prompt like this one: root@f2429f0045db:/projects# I say “like” because the string of letters after the @ sign will be unique to you – container IDs are created randomly. The # sign means you’re currently root, so you have full control over the virtual system, and we’ll be using that to install extra software later on. www.hackingwithswift.com 18
📄 Page
19
Try running the command exit now, and after a few seconds you’ll be back to your regular macOS terminal prompt. What you just did was quit your Docker terminal, which effectively terminates the container. It still exists on your disk, but because “/bin/bash” was the main process of the machine and we just quit it, the container will cease running. Now that you’re back on the macOS terminal, run this command: docker ps. This shows a list of running containers, and you’ll see it doesn’t show any containers. Instead, you’ll see just some column headers where information would be, such as “CONTAINER ID”, “IMAGE”, and so on. The list is empty because it shows only running containers, and exiting our container stopped it from running. We can ask for a list of all containers, running or otherwise, with this command: docker ps -a. Note the extra “-a” in there. This time you’ll see the “projects” container listed, and it will have the status “Exited”. We gave our container the name “projects” so that it’s easy to refer to, so let’s start it now: run docker start projects then wait a few seconds. You should see “projects” written back to your terminal window, then your regular macOS command prompt. That’s Docker’s extremely laconic way of saying “your container is now running.” To verify that “projects” is active, try running the docker ps again. This time you’ll see your container listed with the status “Up about a minute”, showing that it’s active. This time, though, it’s active without us having a Bash terminal inside, so we can carry on working inside the macOS terminal as if Docker weren’t there. So, now we have a fully configured Kitura Docker container up and running, and it’s effectively invisible – you could quit the Mac’s Terminal app altogether and Linux would carry on running in the background. This is the preferred state for containers once you’ve finished development: you start them up, then forget about them. Of course, sometimes you’re going to want to get back into the container to make changes. Later on, for example, we’re going to be installing MySQL inside the container so that we have access to a database. To do that, you need to attach to a container that’s running – to connect to its existing Bash terminal so you’re back at the root prompt. To attach to the “projects” container, run this command: docker attach projects. www.hackingwithswift.com 19
📄 Page
20
You might need to press Return a couple of times, but after a few seconds you should be back at the root prompt inside your container. During development – when you need to run builds frequently – I usually keep the container attached for easy access. Tip: If you want to start your container and attach at the same time, use docker start -i projects. Now that you’re back inside the container, running exit will make it terminate just like before. More commonly you’ll want to detach from the container, which means “get me back to my macOS terminal, but leave the container running.” This is done using two special keystrokes: Ctrl+p followed by Ctrl+q. These should be pressed one after the other rather than together. When you press those two, you’ll immediately be returned to your macOS terminal, but the “projects” container will carry on running. You can attach again using docker attach, then detach, attach, detach, and so on; it will just carry on running. If you ever want to destroy the container, use docker rm projects. If it’s currently running you’ll be told to stop it first, or add the -f parameter to force removal. One last thing before we’re done with Docker: once you’ve created your Kitura container, Docker automatically saves the image required to recreate it. This means you can create more containers from the same image – “ibmcom/kitura-ubuntu” – in just a few seconds, because Docker doesn’t need to download it again. Once again, Docker really is the preferred approach to server-side Swift development. With the setup above, you’re able to write your code using your preferred macOS tools, test using your preferred macOS web browser, but build and run using Linux. This means you’re in the perfect position to transfer your code to a real server when you’re ready, without having to constantly transfer files along the way. www.hackingwithswift.com 20
The above is a preview of the first 20 pages. Register to read the complete e-book.