学习使用 Swift 编写 iOS 应用程序教程 1: Welcome to Programming

你有没有想过iPhone或iPad是如何高效的运行在自己的应用程序的呢?

从来没有比现在更好的学习iOS开发的时机了 - 尤其是应为苹果刚刚发布了一个全新的编程语言Swift!

这个系列的教授如何从初学者到实际的iOS开发, 将带你从基础知识(开始一个Swift编程题目或开始一个command-line应用程序)一路直到做出一个带有漂亮的用户界面且完整的iOS应用程序.

With iOS app development, the sky is the limit(Ps: -_-|||). 这个系列的Swift教程将教你基本的知识, 最后你将会做出你梦寐以求的应用程序!

Note: 如果你是一个初学编程者, 那么这个教程非常适合你! 那么如果你已经有一些编程经验的话或者想要快速学习的话, 请查看这个系列的教程

Getting Started

第一步是下载Xcode - 我们在这个软件里编写应用程序. 你可以在Mac 应用商店里免费下载它.

请确保你的Xcode的最新版本 - 你最少需要Xcode6或以上版本才能运行Swift.
一旦你安装了Xcode, 打开Xcode并且点击上面写着Get started with a playground的按钮.

Note: 如果你看不到这个Welcome to Xcode的窗口, 请点击工具栏 -> Window -> Welcome to Xcode 就能显示它.

playground是一个简单的尝试和学习Swift编码的工具.

你并不能把playground当做一个iPhone的应用程序来运行. 但是他仍然是很有用的, 它可以帮助你了解基本的Swift语法. 不过不用担心, 你很快将创建自己的iPhone应用程序!

设置这个名字为MyPlayground, 平台是iOS, 然后点击Next. 最后保存到你喜欢的地方.

介绍Playgrounds

你将看到你创建的这个playground已经有三行代码了:

1
2
3
4
5
//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"

让我们一次一行的来看这些代码

1
//: Playground - noun: a place where people can play

这是第一行, 其中有两个斜杠, 他表示注释
这行代码是唯一给你或任何其他程序员看的. 它不会影响你的代码功能. 把它看做是”一种写代码笔记(注释)的方法”.

1
import UIKit

第二行导入UIKit, 那么可以把它看做”一堆Apple公司牛B的人写的代码”. 所以你只需要知道在开发中必须加入这个代码.

1
var str = "Hello, playground"

第三行是一个现在你应该注意的重点.

这一行创建了一个str名字的变量, 它的值是Hello, playground. 在窗口的右侧, 你可以看到Xcode实时呈现了这个变量的值.

尝试吧”Hello playground”修改成”Look what I can do!”, 就像这样:

1
var str = "Look what I can do!"

你看到了右侧窗口中就像之前说的那样它发生了改变? 恭喜, 你刚才完成了一个简单的编程!

你自己的计算器

现在让我们看看还有什么可做的. 尝试像这样键入一个基础的数学表达式并且敲击回车来到下一行

1
2 + 2

在窗口的右侧playground会把答案显示出来

很吊, 不是吗? 你可以掌握任何其他的数学运算了.

挑战: 尝试用Playground去计算123*456的结果.

在playground中输入这一行:

1
123*456

在右边你将看到如下答案:

1
56088

使用playground作为一个简单的计算器是很容易的, 所以现在让我们继续前进并进行一些编码! 请删除除了import UIKit外的其他代码, 以便保持一个干净的编码区域.

1
import UIKit

如果没有这一行playground是无法工作的, 所以请务必保留它.

念念碎: 这句是自己强行翻译了下, 大概就是这意思吧.. 原文: It is extremely important that you leave that line there because the Playground will not work without it.

Variables (变量)

接下来, 让我们来多玩玩变量
你使用变量来存储值, 我们通常都是用下面这样的语句来创建一个变量:

1
var yourVariableName: yourType = yourInitialValue

说明:

  • yourVariableName: 任何你喜欢的名字, 如: strage(Ps: 千万不要用中文)
  • yourType: 这是变量的类型, 如: StringInt. 更多时候不同情况下是不同的类型的.
  • yourInitialValue: 你需要给你的变量设置一个任意值, 如 “Look what I can do!” 或 18.

让我们尝试一个例子! 把下面的这些行添加到你的playground中:

1
2
var str: String = "Look what I can do!"
var age: Int = 18

在第一行, 你创建了一个String类型str名称的变量, 并且设置他的初始值为”Look what I can do!”
第二行, 你创建了一个Int类型age名称的变量, 并且设置他的初始值为18
你获得了一个好的开始, 如何使用变量, 但是你可能是想知道StringInt之间的差异和还有那些类型可以使用. 让我们继续往下看.

Types(类型)

下面的这个列表是Swift提供的基本数据类型:

  • Int: 整数类型
  • Double: 带小数的数字类型
  • Bool: 它的值只可能是truefalse
  • String: 可以是一个任意的字符, 如: 字母或字符串

让我们来实际使用这些数据类型. 把下面的这些行添加到你的playground中:

1
2
3
4
var luckyNumber: Int = 7
var costOfCandy: Double = 1.25
var hungry: Bool = true
var name: String = "Ryland"

注意: 每一行的值都会显示在右边的灰色窗口区域. 现在, 尝试修改name的值看下有什么变化.

添加下面这行到你的playground中:

1
name = "Ry"

这一行不需要使用var, 因为这个String对象已经创建好了. 你在这里做的只是改变它存储的值.

挑战: 现在轮到你小试身手了. 在playground的底部, 尝试创建一个代表你喜欢的游戏的变量.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var favoriteGame: String = "Mario Kart"
favoriteGame = "Super Smash Bros."
```Swift

## Constants(常量)
还有一些特别的变量称之为常量.

常量并不是用`var`声明, 而是使用`let`关键字. 当这个常量被创造出来就不能改变它的值了.

只要有可能你应该尽量使用`let`, 而不是`var`, 因为他可以让你的代码运行的更快, 原因是编译器不用去考虑这个值知否会发生改变. 任何数据类型都可用使用常量声明, 就像任意数据类型都可以使用变量一样.

让我们现在尝试创建一些常量. 添加下面的代码到你的playground中:
```Swift
let life: Int = 42
let pi: Double = 3.14
let canTouchThis: Bool = false
let captain: String = "Kirk"

现在尝试重新赋一个值给 captain , 比如说”Hook”. 请吧下面这行代码添加到playground中:

1
captain = "Hook"

注意: 一个红色的小感叹号标志出现在你的左手边. 这里告诉你在你的代码中又错误.

点击这个图标, 查看这个弹出的错误信息Cannot assign to 'let' value 'captain'. 这个告诉你你是使用let初始化的值, 所以你不能更改它.

删除captain = "Hook" 这行 去掉这个错误.

挑战: 创建一个Int类型, 名字为favoriteNumber的常量, 并且设置他的值为你喜欢的数字.

1
let favoriteNumber: Int = 3

Inferred Typing(自动推导类型)

每次都要写类型是不是很累? 没必要担心, Swift比我们想想的要聪明的多了.

有一个Swift新的特征Inferred Typing. 这意味着只要声明和初始化变量时提供的信息足够, Swift可以预测这个数据的类型, 所以你不必每次都指定它.

这个类型不仅能节省你的时间和精力, 还能使你的程序更简洁和高效.

去试试, 找到var luckyNumber: Int = 7这行, 并且替换成下面这行:

1
var luckyNumber = 7

这个似乎并没卵用, 但是从长远来看还是能节省你时间的(Ps: 然并卵)

只记得, 推导类型只有当信息足够的时候才有作用. 如果你想有一个名字为luckyNumberDouble类型变量, 你需要把它设置成7.0(你需要区分清楚7它是一个十进制的整数, 而不是一个小数).

挑战: 你可以去试试, 确保你变量和常量都使用推导类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import UIKit

var str = "Look what I can do!"
var age = 18

var luckyNumber = 7
var costOfCandy = 1.25
var hungry = true
var name = "Ryland"

name = "Ry"

var favoriteGame = "Mario Kart"
favoriteGame = "Super Smash Bros."

let life = 42
let pi = 3.14
let canTouchThis = false
let captain = "Kirk"

let favoriteNumber = 3

Comparison Operators(比较运算符)

就像前面介绍的那样playground可以做简单的数学运算, 它还可以比较数字和值.
这些操作符如下:

  • < Greater Than
  • > Less Than
  • == Equal To
  • <= Greater Than or Equal To
  • && AND
  • || OR
念念碎: 上面几个实在没什么好翻的

你可以使用这些运算符去比较两个值.
让我们来试试! 声明一些变量并添加到你的playground中, 开始比较他们的值

1
2
3
let batmanCoolness = 10
var supermanCoolness = 9
var aquamanCoolness = 1

太吊了, 现在你可以使用两个变量来测试我们的比较运算符了. 将下面的代码块放到playground中.

1
2
3
4
5
batmanCoolness < aquamanCoolness
supermanCoolness >= 8
batmanCoolness == (aquamanCoolness + supermanCoolness)
batmanCoolness > aquamanCoolness && batmanCoolness == (aquamanCoolness + supermanCoolness)
batmanCoolness < supermanCoolness || aquamanCoolness < supermanCoolness

在右侧的窗口中检查得到的结果. playground将会判断你的描述, 并告诉你结果是true还是false

  • AND(&&)语句: 两边的比较一定要是真实的, 最终结果就是true, 如果第一个是假的话, 那么程序根本就不会执行第二个, 因为没有必要.
  • OR(||)语句: 两边只要有一个是真实的, 那么最终结果就是true, 如果第一个是真的话, 那么程序根本就不会执行第二个, 因为没有必要.

挑战: 尝试添加一个变量名为spidermanCoolness的变量, 并给他一个合适的值. 然后尝试使用一些算数运算符(如: >, <, ==, &&, and ||)去比较那些超级英雄的coolness(Ps: 真不知道这是什么鬼, 难道是什么梗吗).(注意batmanCoolnesslet声明的, 你并不能改变它).

1
2
3
var spidermanCoolness = 7
(spidermanCoolness + aquamanCoolness) > supermanCoolness
spidermanCoolness == 7 && aquamanCoolness == 2

If/else 语句

if/else语句, 是计算机当条件为真时, 执行某些代码块, 条件为假时不执行某些代码块的语句(Ps: 就是所谓的流程控制)

我们来试下这个! 添加这个例子到你的playground中:

1
2
3
4
5
6
7
8
9
if (batmanCoolness > spidermanCoolness) {
spidermanCoolness = spidermanCoolness - 1
}
else if (batmanCoolness >= spidermanCoolness) {
spidermanCoolness = spidermanCoolness - 1
}
else {
spidermanCoolness = spidermanCoolness + 1
}

This block of code decreases Spiderman’s coolness if Batman is cooler, but increases Spiderman’s coolness if Spiderman is cooler.

As you can tell from the Playground, Spiderman’s coolness decreases to 6 from the realization that he is not as cool as Batman.

念念碎: Ps: 翻起来好别扭, 哎. 不管他了, 我按自己的理解翻一下

if/else if后面的条件是真的时候, 就会执行后面{}中的代码块了

正如你看到的一样, 这个流程从没有经过else if语句, 即便他也是符合条件的. 这是应为这个流程发现if是符合条件的所以它就不会再执行其它的代码块了.

挑战: 使上面的例子创建一个我们自己的流程控制语句. 请记住, 不是所有的ifelse if 都会满足条件的. 这个程序将可能执行一个else语句, 或继续执行下去.

1
2
3
4
5
6
7
8
9
10
11
12
if(supermanCoolness < spidermanCoolness)  {
supermanCoolness = supermanCoolness - 1
spidermanCoolness = spidermanCoolness + 1
}
else if (supermanCoolness == spidermanCoolness) {
supermanCoolness = > supermanCoolness + 1
spidermanCoolness = spidermanCoolness + 1
}
else {
supermanCoolness = > supermanCoolness + 1
spidermanCoolness = spidermanCoolness - 1
}

Simple Functions(简单的函数)

function(函数)是执行特定任务的(完成特功能的)代码块. 例如: 名字为printMyFavoriteSnack()的函数可以打印出Pringles.

你可已使用自己编写的函数, 或使用其他程序员编写的函数. 例如, Apple提供了大量的内置函数, 你可以在你的应用中使用这些函数.

举一个println()函数的例子. 无论你输入什么到括号内, 它都会出现在控制台内.

让我们来尝试下这个例子. 键入下面的代码到你的playground的最后面

1
println("Hello, World")

你你应该看到”Hello World”输出到了右侧的窗口中.

程序设计中需要用到很多不同的函数. 我们会经常需要用到苹果提供的或别人写的代码, 在你自己的编码过程中你就能体会到了.

挑战: 尝试修改println()方法中的字符串, 把自己吹嘘一番.
并尝试把我们上面用到过的变量打印一下, 看看会发生什么.

1
2
println("Ry is awesome")
println(batmanCoolness)

String Interpolation(字符串中插入值)

能打印字符串到控制台是很好的, 但是如果能把一个字符串和一个值结合起来输出到控制台, 那岂不是更吊.

筒子们好消息! 你可以做到的, 这就是String Interpolation.

当你要这样做是非常好用的: “Sally has (some value) apples.”, 尝试把下面的代码放到playground中去吧:

1
2
var apples = 5
println("Sally has \\(apples) apples")

看到了吗? 只用这种格式\(variable name), 你可以把任何变量或值转换成字符串. 在括号内如果你愿意, 甚至你可以进行其它操作. 添加下面的代码到你playground中.

1
println("Sally has \\(apples - 5) apples")

干得好! 在字符串中插入值, 每个项目中都会用到.

挑战: 现在是时候要结合下你的学会的概念了. 创建两个学生成绩的变量: John(95), Sam(85). 然后, 设计一个if/else语句, 比较John和Sam的等级, 并打印出谁的分数高于谁的分数. 你能做到的!

1
2
3
4
5
6
7
8
9
10
11
12
var johnsGrade = 95
var samsGrade = 82

if (johnsGrade < samsGrade) {
println("\(johnsGrade) is less than \(samsGrade)")
}
else if (johnsGrade > samsGrade) {
println("\(johnsGrade) is greater than \(samsGrade)")
}
else {
println("\(johnsGrade) is equal to \(samsGrade)")
}

While Loops(循环语句)

就像if/else语句一样while语句也是一种流程控制语句. 他们所需要的执行条件是相似的.

当然, while并不是简单只执行一次代码, 而是会继续执行下去, 直到条件不在成立. 键入下面的代码到你的playground中.

1
2
3
4
5
6
var secondsLeft = 3
while (secondsLeft > 0) {
println(secondsLeft)
secondsLeft = secondsLeft - 1
}
println("Blast off!")

请确保你的代码的条件在某些情况下是假的. 你肯定不希望你创建了一个无限循环的代码, 因为他会导致你的程序无法运行循环之后的代码.

当你运行他时, 你可以在右侧看到(3 times)这行, 那是代表println()语句运行的次数. 因为那里有多个值输出, 你可以打一个名为Assistant Editor窗口就可以看到他们了.

像这样做, 去你的工具栏并且选择 View -> Assistant Editor -> Show Assistant Editor.

你可以看到一个Console Output的标志, 你应该能从中看到你的输出:

挑战: 抗木昂, 来尝试写一个自己的while循环 - 例如: 做出一个警察吃一盒甜甜圈的while循环. 千万要记住, 不能让他无限循环.

1
2
3
4
5
6
7
var donutsLeft = 6
while(donutsLeft > 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println("You have \(donutsLeft) donuts left")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;donutsLeft = donutsLeft - 1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println("You eat one donut")
}
println("You are all out of donuts :(")

Break Statement(break语句)

假设你的程序里有某种循环, 如果你想在一个特定情况下, 退出这个循环, 这时你需要用到break. 添加下面的代码到你的playground中.

1
2
3
4
5
6
7
8
9
10
11
var cokesLeft = 7
var fantasLeft = 4

while(cokesLeft > 0) {
println("You have \(cokesLeft) Cokes left.")
cokesLeft = cokesLeft - 1
if(cokesLeft <= fantasLeft) {
break
}
}
println("You stop drinking Cokes.")

在这个例子里, 你在不停的喝可乐, 直到它被喝完. 然而, 你意识到在冰箱里还有芬达(汽水), 你决定停止喝可乐, 因为这个时候你的可乐的量小于等于芬达了. 当这种情况出现时, 你退出了循环, 从而停止喝可乐.

挑战: 现在轮到你来试试. 创建一个while循环, 最终有一个结束点 - 例如: 你上班偷懒, 老板每隔一段时间就会查岗一次. 你需要做好准备, 哈哈.. 在这个循环中, 添加一个当老板快来查岗时退出的语句.

1
2
3
4
5
6
7
8
9
10
11
12
13
var goofOffTime = 10
var bossComing = 0

while(goofOffTime > 0) {
println("Goofing off!")
goofOffTime = goofOffTime - 1
bossComing = bossComing + 1

if(goofOffTime == bossComing) {
break
}
}
println("Done goofing off.")

Continue Statement(Continue语句)

这个continue语句非常类似于break. continue语句并不是退出整个循环, 而是跳出当前的这次循环, 继续执行下一个次循环. 把下面的代码写入你的playground中.

1
2
3
4
5
6
7
8
9
var numbers = 0
while(numbers <= 10) {
if(numbers == 9) {
numbers = numbers + 1
continue
}
println(numbers)
numbers = numbers + 1
}

正如你看到的一样, 除了被continue排除在外的9, 其它的数字都被打印在的控制台中. It’s too bad that 7 ate 9, but for that reason, you can’t include him in our list.(Ps: -_-|||)

挑战: 在你自己的循环里使用continue语句. 找到一个特定值, 使她跳过本次循环, 并能继续循环下去.

1
2
3
4
5
6
7
8
9
10
11
12
println("List of World Wars:")
var ww = 1

while(ww <= 5) {
if(ww == 3 || ww == 4) {
ww = ww + 1
continue
}
println("World War \(ww)")
ww = ww + 1
}
println("That's the beauty of World War V, Lois. It's so intense it skips over the other two. - Peter Griffin")

Optionals(可选类型)

有时由于功能的不同, 你并不知道一个变量的值是多少. 当他没值的时候, 那么他就是nil(空), 这时就需要用到optionals类型了.

可选变量可以包含值或包含nil. 声明一个可选值你可以将其设置为nil.

1
2
var optionalNumber: Int? = 5
optionalNumber = nil

这个?是用来声明可选值的. 如果要判断一个可选值是否有值, 可以使用if let语句. 就像下面的代码一样:

1
if let number = optionalNumber

if let类似于if语句. 如果optionalNumber有一个Int的值, number将被设定为该值并执行大括号中的代码.

或者你可以设计一个else语句来执行optionalNumbernil的情况

挑战: 自己尝试一下, 写一个if let语句判断optionalNumber
是有值还是nil, 并让让输出不同的字符串到控制台.

1
2
3
4
5
6
if let number = optionalNumber  {
println("It is a number")
}
else {
println("It is not a number")
}

Conversion Between Data Types(类型转换)

让我们来看下如何在一个程序中, 进行类型转换. 可选类型可以帮助你进行类型转换. 尝试下面的例子, 将一个字符串转换成一个数字.

1
2
var languagesLearned: String = "3"
var languagesLearnedNum: Int? = languagesLearned.toInt()

在这里, 声明和初始化languages​​Learned的字符串值为"3", 再声明一个languagesLearnedNum并使用toInt()方法进行初始化. 这个方法非常类似之间前学过的println()函数, 只不过, 他是类的一部分. 你以后将会学到更多类似的函数.

toInt()方法是一个已经存在的方法, 所以你得知道这个函数是接收一个字符串类型的值并返回一个Int类型的值. 你同时必须声明一个可选的languagesLearnedNum变量, 使用等于号去接受他的返回值, 因为他的返回值可能是nil, 所以必须使用可选类型. 如果你尝试去转换一个非数字的字符串时, 他的返回值就是nil, 如: “hello. world”.

键入下面的代码, 测试下上面的结论是否正确:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
if let num = languagesLearnedNum  {
println("It is a number")
}
else {
println("It is not a number")
}
```Swift

使用`if let`语句去测试`languagesLearnedNum`是否有值. 如果他有值, 这个值赋值给`num`并执行大括号中的代码. 否则, 执行else后面大括号中的代码.

修改`languagesLearned`这个字符串为"Three", 看下会发生什么. 这个程序应该打印`is not a number`, 因为languagesLearnedNum的值已经被设置成了`nil`, "Three"并不能转换陈`Int`类型.

## Putting it all together(综合练习)

挑战: 最后一个挑战! 尝试创建一个你自己的变量并尝试将这个字符串转换成一个数字. 然后比较这些变量的值并使用`println()`解释这些值的的作用. 这些`println()`解释应该包含在字符串中插入值, 你可以在里面说明哪个值大于/小于哪个值.

![](http://img01.taobaocdn.com/imgextra/i1/1134915854/TB2LRntdpXXXXXkXpXXXXXXXXXX_!!1134915854.png)

```Swift
var tutorialTeam: String = "55"
var editorialTeam = 23

var tutorialTeamNum: Int? = tutorialTeam.toInt()

if let numTutorial = tutorialTeamNum {
if(numTutorial > editorialTeam) {
println("\(numTutorial) is greater than \(editorialTeam)")
}
else if (numTutorial < editorialTeam) {
println("\(numTutorial) is less than \(editorialTeam)")
}
else {
println("\(numTutorial) is equal to \(editorialTeam)")
}
}
else {
println("Invalid entry")
}

Where To Go From Here?

这里是本系列教程使用到现在的playground文件

点击这里到下一部分, 那里你将会用到你学到的知识, 使用Swift 编写一个简单的命令行猜谜游戏!

如果你有任何问题或意见, 请加入论坛下面的讨论.