Chapter    2

iOS Programming Basics

Creating mobile apps for both iOS and web deployment is fun and rewarding. With Xcode in place, you are ready to write code, build, and run iOS apps now. Objective-C had been the primary programming language for iOS apps until Swift was officially announced at the 2014 Apple Worldwide Developers Conference. If you’re just starting to learn iOS programming, you should go with Swift because there is no reason to choose the old way and miss the latest and greatest features. Your next steps should be learning the fundamentals of the following:

  • The Swift programming language
  • The anatomy of the iOS project and the Xcode storyboard editor

The purpose of this chapter is to get you comfortable with reading the Swift code in this book. To achieve this goal, you will be creating a HelloSwift project while learning about Swift programming language highlights.

You will create another Xcode iOS project in the second part of the chapter. All iOS apps have a user interface (UI). You normally start by creating the UI using the most important Xcode tool, the storyboard editor, which draws the UI widgets and components and connects them to your code. You also will see the typical iOS project structures and components while creating this iOS app. You may not need to understand everything about the iOS framework in the beginning, but the first storyboard lesson should be “just enough” for you to get a feel for the different programming paradigm. Later, the materials in Chapters 3 and 4 continue with step-by-step instructions for common programming tasks and framework topics. Follow these mapping instructions, and the ideas will more easily stick with you as you get a broader picture of the whole app.

The Swift Language in a Nutshell

Swift is the newest programming language for creating iOS apps. I am confident that learning the Swift language won’t be the highest hurdle for you; JavaScript and C# developers will pick up Swift code naturally because they are syntactically similar and follow the conventions of typical object-oriented (OO) programming languages. Just to give you a quick preview, Table 2-1 briefly compares JavaScript to Swift.

Table 2-1. Java-to-Swift Language Syntax Comparison in a Nutshell

JavaScript

Swift

<script type="text/javascript" src="scripts/packagename/Xyz.js"></script>

import framework

Xyz.prototype = new SomeClass();

class Xyz : SomeClass

var mProperty;

var mProperty : Int

Xyz.prototype.constructor=Xyz // constructor

init()

var obj = new Xyz();

var obj : Xyz = Xyz()

Xyz.prototype.doWork(arg)

func doWork (arg: String) -> Void

obj.doWork(arg);

obj.doWork(arg)

The Table 2-1 cross-reference refers to how native JavaScript prototype-based inheritance might be used to implement classical inheritance used by Swift, Java, and C#. For those familiar with Prototype and Sencha, the extension libraries and methods for inheritance should make the transition even more straightforward. If you come from a basic JQuery programming background, the syntax of Swift will seem familiar, but the structure of your code will move from a flat list of functions to encapsulated objects and object instances with a hierarchal source structure. In this section, I will not discuss the in-depth OO theory or techniques. However, I do want to point out certain important ideas for pure-JavaScript developers.

HelloSwift with Xcode

Instead of my describing the uses and syntax rules in a formal way, you are going to create a HelloSwift Xcode project and write the code listing from Table 2-1 yourself. You will also perform the following common Xcode programming tasks: creating a class, building and running a project, and using the debugger.

Creating a Swift Command-Line Project

Let’s create a command-line Swift program because it is really simple and you can focus on the Swift language without being sidetracked by other questions.

Follow these instructions to proceed:

  1. Launch Xcode 6 if it is not running. You should see the Welcome to Xcode screen. Click “Create a new Xcode project.” Alternatively, you can select File image Project from the Xcode menu bar.
  2. Choose OS X and then Application in the left column and then select the Command Line Tool template in the “Choose a template for your new project” window (see Figure 2-1).

    9781484209325_Fig02-01.jpg

    Figure 2-1. Choosing an Xcode template

  3. To finish creating the new project with the template, follow the same onscreen instructions that you used to create the LessonOne project in Chapter 1:
    1. Product Name: Enter HelloSwift.
    2. Organization Name: You can use anything here, such as PdaChoice.
    3. Organization Identifier: You can use anything here, such as com.liaollc.
    4. Language: Select Swift.
  4. Click the Next button when done.
  5. Select a folder in which to save your HelloSwift project.
  6. The HelloSwift project appears in the Project Navigator (see Figure 2-2).

9781484209325_Fig02-02.jpg

Figure 2-2. Creating the HelloSwift project

The command-line template creates the main.swift file for you. This is the entry point of the OS X command line tool program. You will be writing code in main.swift to demonstrate common object-oriented code.

Figure 2-2 shows that the typical Xcode workspace contains three areas from left to right and a top toolbar. Inside each area, there are subviews that you may switch to using the selector bars.

  • The Project Navigator area is on the left. Similar to many IDE, this is where you can see the whole project structure and select the file you want to edit. There are other views in this area; for example, you can enable Search view by selecting the Search icon in the selector bar.
  • The Editor area in the middle shows the selected file in its editor, in which you can edit the file, write your code, or modify project settings depending on the file selected. The Console and Variable views are inside the Debug area. Most likely you will want to show them during debugging sessions. You can hide or show them by clicking the toggle buttons on the top and bottom toolbars.
  • The Utility area on the right contains several inspector views that allow you to edit attributes of the whole file or the item selected in the Editor area. Depending on the type of files you select, different types of inspectors will be available in the top selector bar. For example, you will have more inspectors showing in the selector bar if you are editing a screen or UI widgets. The bottom of the area is called the Libraries area. Use the selector bar to select one of the library views. You can drag and drop items from Libraries to the appropriate editor to visually modify file content. You will use the Object Library a lot to compose UIs visually.

Click any of the icons on the selector bars, or hover your mouse over the pointer in Figure 2-2, to see the hover text tips in the workspace to get yourself familiar with Xcode workspace. The subviews appear more condensed than those in most of the IDE I ever experienced, but essentially it is a tool for the same purpose: editing project files and compiling, building, debugging, and running the executables. You will use it repeatedly throughout the book.

Creating a Swift Class

A class is the fundamental building block of any classic OO programming language. A class is a software template that defines what the objects know (state) and how the objects behave (methods). JavaScript uses functions and their prototypes to accomplish the same goal.

While JavaScript web applications often make use of objects by creating and manipulating DOM elements, it is entirely possible to create a JavaScript web application without creating a single new reusable object structure. Using anonymous objects and scripts running in the global scope, referencing function libraries like JQuery, is quite common. Swift, however, requires developers to structure their code into named class types before the objects can be created.

To create a new Swift class, you can create it in the existing main.swift file, or you can follow the Java convention to create it in its own file as shown in the following steps:

  1. Expand the newly created HelloSwift project, right-click the HelloSwift folder to bring up the folder context menu (see Figure 2-3), and select New File.
    1. Select iOS and then Source from the left panel and then select the Swift File template in the “Choose a template for your new file” screen.
    2. Save the file and name it MobileDeveloper.swift. The file should appear in your project.

    9781484209325_Fig02-03.jpg

    Figure 2-3. Create a Swift class from the folder context menu

  2. Enter the code in Listing 2-1 in the MobileDeveloper.swift file to create the MobileDeveloper Swift class.

     Note  Unlike Java, a Swift class doesn’t implicitly inherit from any class. It can be the base class on its own.

    Listing 2-1. Declare MobileDeveloper Class

    class MobileDeveloper {

    }
  3. Create a property called name by declaring a variable inside the class (see Listing 2-2). This is called a stored property in Swift, where the variable type is inferred by the assigned value (known as type inference in Swift).

    Listing 2-2. Stored Property in Swift

    class MobileDeveloper {
       var name  = "" // var type, String, is inferred by the value
    }

 Note  The semicolon (;) is optional for terminating a statement in the same line.

Creating a Swift Protocol

WEB ANALOGY

Though JavaScript has no native comparable for a Swift protocol, web developers using C# or PHP for their server-side code will find comparable examples in the use of interfaces.

In object-oriented programming (OOP), an interface or protocol is essentially a predefined set of behaviors, methods, or properties. The protocol provides no implementation of the methods themselves but rather defines the method names, parameters, and return types. Consumers of the protocol can count on objects they are consuming to properly implement the items defined in the protocol. Protocols allow objects of different types and class inheritance to provide a common, strongly typed interface, thus implementing the concept of polymorphism, one of the fundamental concepts of OOP. You may also provide multiple implementation classes for the same contract and programmatically supply the appropriate instances in the runtime.

In simpler terms, this is a great way to explicitly break dependencies between callers and callees because callers and callees can be implemented independently with clearly defined programming contracts, called protocols in Swift.

Create a Swift protocol called Programmer by doing the following:

  1. Right-click the HelloSwift folder to create the Programmer.swift file.
  2. In the Editor area, create the Programmer protocol with the method writeCode(...), as shown in Listing 2-3.

    Listing 2-3. Declare the Programmer Protocol

    protocol Programmer {
      func writeCode(arg: String) -> Void
    }

Implementing the Protocol

To conform to the expected behavior defined in a Swift protocol, the tagged class must implement the methods defined in the protocol. To make the MobileDeveloper class implement the Programmer protocol, do the following:

  1. Modify MobileDeveloper.swift and declare the MobileDeveloper class to implement the Programmer protocol, as shown in Listing 2-4.

    Listing 2-4. Conform to MobileDeveloper Protocol

    class MobileDeveloper : Programmer {
      ...
    }

     Note  If the Swift class already has a superclass, list the superclass name before any protocols it adopts, followed by a comma (,)—for example:
    class MobileDeveloper : Person, Programmer

  2. Provide the writeCode(...) method implementation body, as shown in Listing 2-5.

    Listing 2-5. Method Body

    class MobileDeveloper: Programmer {
      ...
      func writeCode(arg: String) -> Void {
        println("(self.name) wrote: Hello, (arg)")
      }
    }

 Note  (self.name) is evaluated first inside the quoted String literal.

Using the Swift Instance

WEB ANALOGY

var you = new MobileDeveloper();
you.setName("You");
you.writeCode("Javascript");

You have created a Swift MobileDeveloper class and implemented the Programmer obligations in pretty much the same way you would in Java with some minor syntax differences. To use the class, it is the same as Java in principle, calling a method defined in the receiver from the sender. Modify HelloSwift/main.swift as shown in Listing 2-6.

Listing 2-6. Swift Entry main.swift

var you = MobileDeveloper()
you.name = "You"
you.writeCode("Java")

Implementing Access Control

WEB ANALOGY

While JavaScript doesn’t have access control keywords, many JavaScript developers use closures and constructor variables to create methods and variables with private access from the object.

Here’s an example:

function MyObject() {
    var private;
    this.getPrivate = function (arg) {
        return private;
    }
    this.setPrivate = function (val) {
       private=val;
    }
}

var test =new MyObject();
test.setVal("My private value");
console.log("Private value is "+test.getVal());

Encapsulation is one of the fundamental principles of OOP; in a nutshell, certain internal states or methods are meant only for internal implementations but not to be used directly by the callers. Swift provides access controllers to prevent access to the members or methods that developers decide to hide. This is achieved with access modifiers for files and with module access controls using the following keywords as the access modifiers: private, public, and internal. The internal access modifier is the default access control that is public to the whole module but not visible when the modules are imported. If you are building a reusable module that can be imported by other program, use the public access modifier to expose the API to another module. The private access modifier makes your custom classes or type or members visible only within the file scope.

To demonstrate the private access control, modify MobileDeveloper.swift as shown in Listing 2-7.

Listing 2-7. The private Access Modifier in MobileDeveloper

private class MobileDeveloper {
  var name  = "" // var type is infered by the value
  
  func writeCode(arg: String) -> Void {
    // some dummy implementation
    println("(self.name) wrote: Hello, (arg)")
  }
  
  private func doPrivateWork() {
    println(">> doPrivateWork")
  }
}

// another class in the same source file
class TestDriver {
  func testDoPrivateWork() -> Void {
    var developer = MobileDeveloper()
    developer.doPrivateWork()
  }
}

Since TestDriver is implemented in the same source file, the code in TestDriver still can access the private class and its private method. However, the MobileDeveloper class in Listing 2-6 becomes not visible anymore from the main.swift file.

Using the Xcode Debugger

Knowing how to use the debugger when creating software can make a big difference in your productivity. Do the following to see the common debugging tasks in the Xcode debugger:

  1. To set a breakpoint, click the line number in the Xcode code editor. Figure 2-4 depicts a breakpoint that was set in the main.swift file.

    9781484209325_Fig02-04.jpg

    Figure 2-4. Breakpoint

     Note  To turn on line numbers in Xcode editors, go to the Xcode top menu bar and select Xcode image Preferences image Text Editing image Show Line Numbers. There are other handy settings there that you may want to look at (for example, shortcut keys are defined under Key Binding).

  2. To run the HelloSwift project, click the triangle-shaped Run button in the upper-left corner or press flower.jpg+R (see Figure 2-5).

    9781484209325_Fig02-05.jpg

    Figure 2-5. Xcode debugging

  3. The Swift program should start and then stop at the breakpoint as shown in Figure 2-5. While debugging, I normally toggle the following subviews on or off as needed:
    1. Hide the navigation area or switch to the Debug Navigator to view threads.
    2. Show the Debug area with the Debug toolbar and Variable and Console views.
    3. Hide the Utility area.

Stack Trace (in Debug navigator), Variables Inspector, Output Console, and the Debug toolbar (in Debug area) have a similar look and feel in most IDEs, including Xcode.

This completes your HelloSwift application exercise. As you follow along with the iOS projects in this book, you will discover more productivity tips in the Xcode IDE.

More About the Swift Language

The new Xcode environment and the Swift language have some pretty neat features, so it’s worth taking a quick look at them now.

To go through this section, it is best to use the new Xcode feature called playgrounds. Launch Xcode and select “Get started with a playground.” You can write any code snippets you want and see the result or syntax errors immediately. Figure 2-6 shows the playground; you write code in the left panel, and the right panel renders the result immediately.

9781484209325_Fig02-06.jpg

Figure 2-6. Xcode playground

JAVASCRIPT ANALOGY

Browser developer tools, JavaScript console, or JSFiddle give you immediate feedback for the Javascript code you write.

Variables and Constants

You declare a variable using the var keyword, and you use let to declare constants. Similar to JavaScript, Swift variables are global if defined not within any enclosing brackets. Listing 2-8 depicts the usage of Swift variables.

Listing 2-8. Common Variables Usages

var GlobalVar : String = "Global Variable"; // global scope not enclosed in any brackets

class MyClass {
  var mProperty : String = ""; // class scope
  let mConstant : Int = 0; // constant
  
  func myMethod(arg : String) {
    var aVar : String = ""; // local variable in method scope
    let aConstant = 1;
  }
}

Type Safety and Type Inference

Unlike Swift, JavaScript is a weakly typed language. A JavaScript variable can be assigned values of any type or passed as a parameter to a function that expects a value of a completely different type or no parameters at all. JavaScript’s lack of strong typing can result in code that is vulnerable to runtime errors, especially as web applications grow in size and complexity.

As a strongly typed language, Swift requires that all variables be declared with a type that they will keep through their lifetime, with the compiler flagging any mismatched types. If the type of a variable can be inferred by its value, you don’t need to explicitly declare the type. Listing 2-9 is essentially the same as Listing 2-8. The Swift type inference feature encourages developers to assign initial values that reduce common errors because of variables not initialized yet.

Listing 2-9. Common Type Inference Usages

var GlobalVar = "Global Variable"

class MyClass {
  var mProperty = ""
  let mConstant = 0
  
  func myMethod(arg : String) {
    var aVar = "";
    let aConstant = 1
  }
}

Optional Variable

The optional variables are declared with the type and a postfixed question mark (?), called an optional type. This indicates the value it contains may be absent (nil, equivalent to undefined in JavaScript) for the intended type. For example, Listing 2-10 depicts the difference in Swift and JavaScript for converting a string to an integer.

Listing 2-10. Optional Type in Swift vs. Handle Exception in JavaScript

////// Javascript TypeError
function StringToInt(str) {

}
var intStr;
var int

function useObject(objParm) {
        try {
            objParm.badFunction()
        } catch(err) {
            console.log(err);
        }
}

var undefinedObject;
useObject(undefinedObject);

////// Swift Optional Int
var intStr = "123"
var myInt : Int? = intStr.toInt() // myInt can be nil

Optionals make the Swift language more type-safe and more robust by encouraging developers to understand whether the variable can be absent. Listing 2-11 demonstrates two practical Swift optional usages.

  • Forced unwrapping, which uses a postfixed exclamation pointer (!)
  • Optional binding, which automatically unwrap the variable in the if or while statement

Listing 2-11. Swift Optional Int

var intStr = "123"
var myOptionalInt : Int? = intStr.toInt() // Optional Int
if myOptionalInt != nil {
  var myInt = myOptionalInt! // Unwrap Int? to Int
  println("unwrapped Int: (myInt)")
}

// optional binding used in if and while local scope.
if var myInt = intStr.toInt() {
  // myInt is auto unwrapped
  println("unwrapped and local scope: (myInt)")
}

Implicitly Unwrapped Optionals

For the situations where a variable will always have a value after the value is set, you declare the variable as an implicitly unwrapped optional postfixed with ! instead of ?, as in var delegate: MyDelegate!.

Any of the optionals’ usages described earlier are applicable here. You treat them as optionals, but you don’t need to force unwrapping the variable (Implicitly Unwrapped Optionals). You commonly see this usage in the iOS framework for properties that are initialized somewhere else (in other words, by the caller). Particularly, iOS frameworks embed delegate properties everywhere. These delegates are declared as implicitly unwrapped optionals, but their values are typically assigned by the caller. As another example, UI widgets are normally drawn in the storyboard editor  and connect to your code as IBOutlet properties. These IBOutlet properties are declared as implicitly unwrapped optionals. I just wanted to give you a quick heads up for now because you will see these usages frequently later in this book.

Tuples

WEB ANALOGY

Tuples are equivalent to JavaScript objects created by literal notation, sometimes called anonymous objects.

Here’s an example:

var xyz  = {x: 2, y: 3, z: 0};
var total=xyz.x+xyz.y;
console.log("Total is now:"+total);
// Displays: total is now 5

Tuples group multiple values into a single compound value. For example, you can pass or return multiple values without creating a class or a struct (structs are also supported in Swift). Listing 2-12 shows the most common tuple usages.

Listing 2-12. Common Tuple Usages

var xyz  = (x: 0, y: 0, z: 0)
println("xyz (xyz) x is: (xyz.x) y is: (xyz.y) z is: (xyz.z)")

// or decompose tuples
var xy : (Int, Int) = (1, 1) // or simply var xy = (1, 1)
var (a, b) = xy
println("xy (xy) x is: (a) y is: (b)")

func httpResponse() -> (rc: Int, status: String) {
  return (200, "OK")
}

var resp = httpResponse()
println("resp is: (resp.rc) (resp.status)")

Collections

JAVASCRIPT ANALOGY

JavaScript arrays are used as collections, having case-sensitive string names as the unique index.

Here’s a JavaScript example:

var colors = ['red','green','blue'];
var colorDictionary = {};
colorDictionary.red = colors[0];

Array and Dictionary are the two Swift collections. Listing 2-13 shows the common usages, which include the following:

  • Initialization
  • Accessing and modifying elements using subscript syntax
  • Common collection APIs

Listing 2-13. Common Array and Dictionary Usages

// collections
var emptyArray = Array<String>() // or [String]()
var emptyDict = Dictionary<Int, String>() // [Int: String]()
var colors = ["red", "green", "blue"]
var colorDictionary = ["r" : "red", "g" : "green", "b" : "blue"]
colors.append("alpha") // or: colors += "alpha"
colorDictionary["a"] = colors[3]
colors.insert("pink", atIndex: 2)
colors.removeAtIndex(2)
println(colors.isEmpty ? "empty" : "(colors.count)")

The constant Dictionary or Array is immutable, meaning it is not allowed to add or remove elements or modify existing items. On the other hand, the variable Dictionary or Array is mutable. JavaScript has no concept of constants or access modifiers.

Control Flow

Similar to JavaScript, in Swift you use if and switch to make conditionals and use for-in, for, while, and do-while to make loops. Parentheses around the condition or loop variable are optional. Braces around the body are required. Listing 2-14 demonstrates the following common control flow usages:

  • for-loop
  • for-in
  • while-loop

Listing 2-14. Control Flows

for (var idx = 0; idx < 10; idx++) { // optional parenthesis
  println("for-loop: (idx)")
}

for item in [1,2,3,4,5] { // or for item in 1...5
  println("for-in: (item)")
}
for c in "HelloSwift" { // loop thru characters
  print(c)
}

for (key, value) in colorDictionary {
  println("for-in dictionary:(key) - (value)")
}

// while-loop, or do-while that run at least once
var idx = 0
while idx < colors.count {
  println("while-loop:  (colors[idx])")
  idx++
}

Switch

In Swift, the switch cases can be any types in addition to int primitive data. Listing 2-15 shows the following improved control flow switch usages in Swift:

  • Combined cases and always break implicitly
  • Cases with ranges
  • Cases with tuples

Listing 2-15. Improved Switch

var condition = "red"
switch condition {
case "red", "green", "blue": // combined cases
  println("(condition) is a prime color")
  // always break implicitly (no follow thru)
case "RED", "GREEN", "BLUE":
  println("(condition) is a prime color in uppercase")
default: // not optional anymore
  println("(condition) is not prime color")
}

var range = 9 // by range
switch range {
case 0:
  println("zero")
case 0...9:
  println("one-digit number")
case 10...99:
  println("two-digit number")
case 10...999: // first hit first
  println("three-digit number")
default:
  println("four or more digits")
}

var coord = (0, 1)
switch coord { // by tuples
case (0...Int.max, 0...Int.max):
  println("1st quad")
case (Int.min...0, 0...Int.max):
  println("2nd quad")
case (Int.min...0, Int.min...0):
  println("3rd quad")
case (0...Int.max, Int.min...0):
  println("4th quad")
default:
  println("on axis")
}

A switch can bind the matched value within its local scope. You can specify a where clause to test the condition, too. Listing 2-16 demonstrates both value bindings.

Listing 2-16. Temporary Value Binding and Using the where Clause

var rect = (10, 10)
switch rect {
case let (w, h) where w == h:
  println("((w, h)) is a square")
default:
  println("rectangle but not square")
}

Enumerations

You use an enum to define a common type for a group of named and related constant values. JavaScript has no analogous concept, often leaving developers passing numeric values to functions with code comments to explain the meaning of each numeric value. After the enumeration is defined, you use it just as a Swift type that is type-safe. Listing 2-17 shows the following common enum usages:

  • Enum with or without raw values
  • Enum associated with values

Listing 2-17. Common Enum Usages

enum DayOfWeek { // raw value is optional
  case SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
  THURSDAY, FRIDAY, SATURDAY
}

var aDay = DayOfWeek.SUNDAY
switch aDay {
case DayOfWeek.SATURDAY, DayOfWeek.SUNDAY:
  println("(aDay) is weekend")
default:
  println("(aDay) is weekday")
}

enum DayOfWeek2 :  String { // assign raw value
  case SUNDAY = "Sun", MONDAY = "Mon", TUESDAY = "Tue",
  WEDNESDAY = "Wed", THURSDAY = "Thu", FRIDAY = "Fri", SATURDAY = "Sat"
}

var aDay2 = DayOfWeek2.SUNDAY
switch aDay2 {
case DayOfWeek2.SATURDAY, DayOfWeek2.SUNDAY:
  println("(aDay2.rawValue) is weekend")
default:
  println("(aDay2.rawValue) is weekday")
}

// associated values
enum Color {
  case RGB(Int, Int, Int)
  case HSB(Float, Float, Float)
}

var aColor = Color.RGB(255, 0, 0)
switch aColor {
case var Color.RGB(r, g, b):
  println("R: (r) G: (g) B: (b) ")
default:
  println("")
}

Functions

Swift functions are declared with the func keyword. Unlike JavaScript functions, which do not declare a return type, the parameter and return types must be declared after the parameter names and function signature. Here are the typical Swift function usages you most likely will encounter (see Listing 2-18):

  • Tuples: You can return multiple values without creating a struct or class (see Listing 2-11).
  • External parameter names: You should treat external parameter names as part of the function signature. All of the iOS Objective-C SDK APIs are ported to Swift with external parameter names.
  • Default parameter values: Not only does this feature provide a default value, but it also makes method overloading easier in many situations, as opposed to method chaining.
  • Variadic parameters: This is convienent to specify functions with variable number of function parameters without using Array type.
  • Function parameters: These are constant by default.
  • Swift functions: These are of a reference type. Just as you can with a class type, you can pass functions as function parameters or return them as function return types. In practice, you would use closure expressions more frequently.
  • Closure expression: This is one of the three types of closure defined in Swift. It is an unnamed self-contained block of code that can be passed as a function parameter.

 Note  The second type of closure is the global function mentioned right here, which is actually a special case of closure. The third type of closure is called a nested function declared inside a function, which is not used in this book.

Listing 2-18. Function Usages

func doWork(parm : String) -> String { // simple form
  return "TODO: " + parm
}
println(doWork("Swift"))

// External parameter names is part of the func signature
func doWork2(name parm : String) -> String {
// arg = arg.uppercaseString; // error: constant parm
  return "TODO: " + parm
}
println(doWork2(name: "Swift"))

// use # to indicate same name for internal and external
func doWork3(#name: String) -> String {
  return "TODO: " + name
}
println(doWork3(name: "Swift"))

// With default parm value, it also implies #, same external name
func doWork4(name: String = "Swift") -> String {
  return "TODO: " + name
}
println(doWork4()) // default parm value

// parm is constant by default unless declaring it with var
func doWork5(var name: String = "Swift") -> String {
  name = name.uppercaseString;
  return "TODO: " + name;
}

// variadic parms
func sumNumbers(parms : Int...) -> Int {
  var sum = 0
  for number in parms {
    sum += number
  }
  return sum
}
println(sumNumbers(2,5,8))

// func is a type, can be used for parm or return type.
func separateByAnd(p1: String, p2: String) -> String {
  return p1 + " and " + p2
}
func printTwoString(p1: String, p2: String, format: (String, String)->String) {
  println(format(p1, p2))
}
printTwoString("Horse", "Carrot", separateByAnd)

// closure expression is unnamed func
printTwoString("Horse", "Carrot",
  {(p1: String, p2: String) -> String in
    return p1 + " and " + p2
  })
printTwoString("Horse", "Carrot",
  {p1, p2 in // type inferences
    return p1 + " and " + p2
  })
printTwoString("Horse", "Carrot",
  { // Inference and shorthanded parm names, $0, $1 ...
    return $0 + " and " + $1
  })

You may get by with not using most of the shorthand options at first, but for iOS programming, you definitely will need to get used to the external parameter names because they are used heavily in iOS frameworks.

Class

Like other classic OO languages, Swift uses classes to define the shared functionality and properties of a given type. Though many web developers may be unfamiliar with the creation of classes using prototype inheritance in JavaScript, almost every web developer has made use of the JavaScript classes that define the support for DOM manipulation. The simplest Swift class form can be depicted as shown in Listing 2-19.

Listing 2-19. Simple Swift Class

class SimpleClass {
  var mProperty : Int = 0
  var mConstant : String = "MyKey"
  func myMethod(name: String) -> Void { println(name)}
}

Property

Listing 2-20 demonstrates the following Swift property usages:

  • Stored property: Analogous to normal JavaScript object property.
  • Computed property: For derived values, executes code, but referenced as a property.
  • Property observer: Optional coding block that responds to changes in a property value.
  • Type property: A property with scope defined at the class level, rather than at the instance level. Stored type properties are not supported in the Swift class type yet. Since struct type property is now supported, you may choose to define an inner struct for porting Java static variables as a workaround for now.

Listing 2-20. Swift Class Property

class MyClass {
  var width = 10, height = 10 // stored properties

  // computed properties, can have set as well
  var size : Int {
    get {
      return width * height
    }
  }
  
  var size2 : Int { // readonly, shorthanded
    return width * height
  }
  
  // property observer
  var depth : Int = 10 {
    willSet {
      println("depth ((depth)) will be set to (newValue)")
    }
    didSet {
      println("depth ((depth)) was set from (oldValue)")
    }
  }
  
  // Swift class Type property,
  class var MyComputedTypeProperty : String {
    return "Only computed Type property is supported in class type for now"
  }
  
  // use struct stored Type property as a workaround
  struct MyStatic {
    static let MyConst = "final static in Java"
    static var MyVar: String?
  }
}

println(MyClass.MyStatic.MyConst)
MyClass.MyStatic.MyVar = "class var in Java"
println(MyClass.MyStatic.MyVar)

Method

Methods are functions defined inside a type context (in other words, a class). They are still functions as described previously (see Listing 2-17). You can define instance methods, which are called on an instance of a class, or type methods, which are called on the class itself. Listing 2-21 shows the following typical method usages:

  • Method declarations enforce external names implicitly, except for the first parameter. This is different from the global function (see the “Functions” section). All iOS Objective-C methods are ported to Swift using this convention.
  • Use class func to declare class type methods, or use static func to declare type methods in struct or enum types.

Listing 2-21. Common Method Usages

class MyClass {
  
///////// methods copied from Listing 2-17 //////////
  func doWork(parm : String) -> String {
    return "Do something with: " + parm
  }
  
  // default parm value, always imply externl parm name
  func doWork2(name: String = "Swift") -> String {
    return "Do something with: " + name
  }
  
  // func is a type, can be used for parm or return type.
  func separateByAnd(p1: String, p2: String) -> String {
    return p1 + " and " + p2
  }

  func printTwoString(p1:String, p2:String, format:(String, String)->String) {
    println(format(p1, p2))
  }

  // Type methods, methods which can be called on the Class
  class func DoWork(parm : String) -> String {
    return "Do something with: " + parm
  }
}

var c = MyClass()
println(c.doWork("Swift"))
println(c.doWork2()) // default parm value
println(c.doWork2(name: "Swift")) // external name enforced

// closure is unnamed func
c.printTwoString("Horse", p2: "Carrot", format: c.separateByAnd)
// Inference and shorthanded parm names apply to method, too.
c.printTwoString("Apple", p2: "Orange", format: {
  return $0 + " and " + $1
  })

MyClass.DoWork("Swift Type method")

Reference Type vs. Value Types

Just as in JavaScript, reference types are passed by reference (the reference to the instance is copied to another variable), and values types are passed by copy (the whole value type instance is copied to another memory space). However, you do need to pay attention to certain differences.

  • Custom classes are reference types. Primitives, structs, and enums are value types. This is similar to JavaScript, where objects and functions are passed by reference and primitives are passed by value.
  • Unlike JavaScript, arrays are value types (they are not classes in Swift). This is nice but may surprise you in the beginning.
  • Since Dictionary and Array are value types, they are copied during assignment. The contained items are also deep-copied if they are value types.
  • You will encounter the Swift NSString, NSArray, and NSDictionary because they are directly ported from counterpart Objective-C framework classes. They are all implemented as classes and are thus reference types.

iOS Project Anatomy

Most GUI apps are composed of more than programming source code; for example, a typical iOS project contains Swift or Objective-C source code, libraries, storyboard files, images or multimedia noncode application resources, an application-information property Info.plist file, and so forth. Xcode compiles and builds the whole project and bundles all the artifacts required for an app into an archive file with an .app file extension and signs the .app file with the appropriate signing certificate.

Let’s create a simple HelloMobile Xcode project so that you can visualize these software artifacts in a typical iOS project.

  • It has only one screen.
  • On this screen, it has an EditText to take user input. When the Hello button is pressed, it shows a greeting in a TextView.

To create the HelloMobile iOS app, start Xcode and proceed with the following steps:

  1. Select “Create a new Xcode project” on the Welcome to Xcode launch screen. Or, you can select File image New image Project from Xcode’s top menu bar.
  2. Select iOS Application and then choose Single View Application as the project template (see Figure 2-7).

    9781484209325_Fig02-07.jpg

    Figure 2-7. Single View Application template

  3. Complete the following fields to finish creating the new project:
    1. Product Name: Enter HelloMobile.
    2. Organization Name: Use something like PdaChoice.
    3. Organization Identifier: Use something like com.liaollc.
    4. Language: Select Swift.
  4. Click the Next button when done.
  5. Select a folder to save your HelloMobile project.

The bare-bones HelloMobile iOS project is created, and it now appears in the Xcode Project Navigator area (see Figure 2-8).

9781484209325_Fig02-08.jpg

Figure 2-8. HelloMobile project

It is immediately runnable. Let’s examine the typical iOS software artifacts in an Xcode project, which comprise the iOS app.

  • Swift classes in .swift files. There are two classes.
  1. AppDelegate.swift: Each iOS app must have one AppDelegate class. This is the entry point of the iOS program. You don’t need to modify this file if your program doesn’t need to track the global application state.
  2. ViewController.swift: There is a ViewController class paired with the content view. The intended purpose is the content view controller for the content view.
  • Main.storyboard file with .storyboard file extension.
  1. You commonly create one storyboard scene per content view and use only one storyboard file for all content views so you can visually implement the linkages among them.
  2. Images.xcassets. This is where you put your image assets, in what is called the assets catalog. Developers should provide different assets for each device configuration. This is done for the same purpose as providing alternative resources in Android.
  3. PNG and JPEG image formats are both supported as of this writing. Using the assets catalog is not a must. You may drop any resource files into the Xcode project. (You may want to create a folder to organize them yourself).
  • Info.plist file. This file describes how the app is configured and the required capabilities the system needs to know.
  1. You may glance through this file to get a feel for the configurations and settings that Xcode needs to know about the app. Xcode initially creates it in XML format, which you can edit directly.
  • Like most web development projects, you can organize your project structure in any way you want. Many web developers follow a strict naming convention pattern for the storage of their CSS files, images, and so on, and Swift will allow you to do the same. Swift currently has no concept of namespaces. All classes in Swift are scoped by the module they are defined in (that is, NSLog Swift scopes as Foundation.NSLog). I normally manually organize my Swift classes in folders structured by functionality and create a res folder to organize any resources files, including the Images.xcassets.
  1. In Xcode, the folder can be an actual folder in light blue (for example, the Images.xcassets folder).
  2. Folders in Xcode can also be just a tag, called a group, that is yellow (for example, HelloMobile, Supporting Files, and so on). Their actual location could be in any of the physical subfolders, but you should not care.
  • Xcode 6 automatically creates a unit test target for your primary project. It contains a TestCase class skeleton in which you can write your unit test code. Although you will not use this feature in this book, it is actually useful.
  • Project Settings and Target Settings instruct Xcode how to compile and build the projects. To show the Project Settings, select the top-level application name in the Xcode Project Navigator area. The Project Settings editor shows in the Editor area. For this simple project, you don’t need to modify anything. But you should glance through the editor to get a quick idea of what Xcode requires to compile and build the executable.

The iOS app is not completed yet, but it has everything a typical iOS app should have.

Xcode Storyboard

WEB ANALOGY

There is no storyboard-like feature in most web dev environments. Views are normally either built one at a time in a quasi-WYSIWIG markup editor (Visual Studio, Eclipse, and so on) or, more often than not, built in a text editor for use with libraries such as Handlebars or Knockout. Even web developers familiar with Sencha Architect will find the storyboard designer’s presentation of application flow to be tremendously powerful and intuitive by comparison.

Use the Xcode storyboarding feature to visually compose the UI for your app. As its name implies, not only does it create individual screens and UI widgets, but it also lets you compose the whole app as one storyboard. Since iOS apps are all GUI apps, this tool will greatly determine your productivity in creating iOS apps through the following actions:

  • Drag and drop a View Controller from the Object Library to create a content view, called a storyboard scene.
  • Drag and drop UI widgets from the Object Library onto the storyboard scene (content view) and position each widget appropriately.
  • Implement Auto Layout to make the UI widgets and content view flexible and adaptive for various screen sizes, similar to the Android relative layout manager.
  • Implement specific content views for specific size classes of different devices.
  • Link the UI widgets to the properties of the view controller via outlets and write code to respond to UI widget events.
  • You can even draw the view controller transitions all within the storyboard editor.

There are other subviews in the Utility area that you can select from the top selector toolbar. All of them are important; you should take a moment to get familiar with them.

  • File Inspector: This shows you the actual file identity and document type options in Xcode.
  • Quick Help Inspector: This shows you the reference doc.
  • Identity Inspector: This shows you the Swift class from SDK or your custom class that is associated with the item in the storyboard.
  • Attributes Inspector: This is your primary interest now. You will see different attributes for different widgets.
  • Size Inspector: This shows you the rectangular area in which the widget is located.
  • Connections Inspector: This lets you draw the connection to the view controller. I will discuss this later in the book (see “Interact with Content View” in Chapter 3).

Now is the time for you to get familiar with the Xcode storyboarding feature. The iOS HelloMobile project doesn’t look like the complete app yet; it has only one screen in the Main.storyboard file, which is empty. You will need to add three UI widgets: EditText, TextView, and a hello Button.

First you will implement the user interface of the HelloMobile iOS app. Xcode storyboards provide everything you need for this mission.

Object Library and Attributes Inspector

WEB ANALOGY

Many web developers find themselves building their markup and code in a tool of their choosing, running the application in a browser with the developer tools open, and inspecting and manipulating the attributes of their layout directly from the browser.

You need to add three UI widgets to the content view using the following steps:

  1. Select the Main.storyboard file in the Project Navigator. Figure 2-10 depicts the storyboard editor in the Editor area. Currently, there is only one screen, known as a storyboard scene.
  2. Select the Object Library from the Library selector bar in the Utility area. This is where you can find the UI widgets and elements to compose the storyboard.
  3. Optionally, to make more room for your storyboard editor, you may hide the navigation and Debug areas by selecting the toggle buttons, as indicated in Figure 2-9.

    9781484209325_Fig02-09.jpg

    Figure 2-9. Select UI components from the Object Library

  4. I will talk about size class, an important new iOS 8 feature, in Chapter 3. For now, disable it by unchecking Use Size Classes in the File Inspector of the Utility area, as shown in Figure 2-10. This will give you a better WYSIWYG storyboard editor.

    9781484209325_Fig02-10.jpg

    Figure 2-10. Disable Use Size Classes in File Inspector

  5. To add the UI widget to storyboard scene, find the desired UI widget from the Object Library and drag it to the existing view in the storyboard scene. Both Android and iOS screens must have one root view, and any view element should be added to a parent view. This forms the parent-child view hierarchy.
    1. You must select the parent view (see the pointer in Figure 2-11) first so you can drop the TextField element onto it.
    2. You may browse and select the UI widgets from Object Library. The list is long, so the search bar on the bottom is useful for finding the right widget. Type the name of the iOS widget, as shown in Figure 2-10, or just type in your best guess for as many characters as needed.

       Tip  The iOS widgets you need are called UITextField, UILabel, and UIButton.

    3. To position the newly added TextField, drag it to where you want it to be. Xcode gives you guide lines to show you when the widgets are at certain positions of the common interests, such as in the center, or aligned to any other widgets (see Figure 2-11).

      9781484209325_Fig02-11.jpg

      Figure 2-11. Guide lines

    4. Figure 2-12 shows the three simple UI widgets added to the storyboard scene.

      9781484209325_Fig02-12.jpg

      Figure 2-12. Three simple UI widgets

  6. The attributes of UI widgets in Swift control the look, feel, and behavior of the widgets, and you can change them visually. You can find and modify these attributes in the Attributes Inspector located in the Utility area. Set the attributes of the TextField like this:
    1. Set the font size to System 24.
    2. For the placeholder, enter Enter a Name, e.g., You.
    3. Set the alignment to center.
    4. TextField has a handful of attributes. Glance through them and you should have no problem relating them to the counterpart attributes you normally use in an HTML element.
    5. Switch to the Size Inspector view and change the width to 200. You will need to drag the TextField to reposition it to center horizontally.
  7. To make the Label widget like the Android counterpart TextView, modify the following attributes:
    1. For Text, enter something like Hello World!.
    2. Set Font to something like System 20 or Headline.
    3. Set Alignment to center.
    4. Set Lines to 1.
    5. Switch to the Size Inspector and change the width to 200. You will need to drag the label to reposition it to center horizontally.
  8. To make the Button widget like the Android counterpart, modify the following attributes:
    1. Text: Hello World!
    2. Title: Hello ...
  9. To preview your storyboard in Xcode, click the Assistant Editor button on the toolbar and select Preview in the Assistant Editor, as shown in Figure 2-13.

    9781484209325_Fig02-13.jpg

    Figure 2-13. Three simple widgets added to the storyboard

The look and feel in portrait mode is close enough for our purposes, in other words, using a storyboard to visually compose the content view without writing a single line of code. The iOS HelloMobile is not completed yet. The Hello button doesn’t read “Hello...,” and the landscape mode is not acceptable yet. Both are important topics and have their own sections in Chapter 3.

In this exercise, I just wanted to give you a quick look at the Xcode storyboard editor. The Xcode workspace could be a little overwhelming if you are not used to using any IDE. Spend a moment to get familiar with the Xcode workspace, including the storyboard editor, the Utility area, the selector toolbar, and so forth. Xcode storyboarding is an important tool that will greatly influence your productivity when creating iOS apps.

Summary

On the surface, you learned about a lot of things in this chapter. I started with a discussion of Swift–JavaScript language comparisons to show their similarities, and then I went over Swift language topics to highlight the new language features. However, the rest of the book will focus on iOS programming instead of the Swift language. The code will address readability as opposed to being concise using shorthanded notations or Swift tricks. You surely won’t have a problem reading all the Swift code in the rest of the book. Sooner or later, though, you will need the reference document to the Swift programming language, which is available free in iTunes (https://itunes.apple.com/us/book/swift-programming-language/id881256329).

You created a HelloMobile iOS project using Xcode to visualize a typical iOS application structure. You also got your first taste of the Xcode storyboard, which is important and which you will use for every iOS app, including all the sample projects in this book, so plan on revisiting the storyboard repeatedly.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset