Chapter    2

iOS Programming Basics

Creating mobile apps for both iOS and Android 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 great 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 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, 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 feel 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, the newest programming language for creating iOS apps, has many similar rules and aspects of language syntax to Java. I am very confident that learning the Swift language won’t be the highest hurdle for you; Java or C# developers will pick up Swift code naturally. Just to give you a quick preview, Table 2-1 depicts a quick Java-to-Swift comparison:

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

image

Swift also defines file and the module access control: private, public, and internal. Although they have different meanings from their Java counterparts, if you define each class in each own file, the private/public access controls can be used the same way. The default internal access control is also public to any file in the same project, but is not visible when being imported to other projects. The Swift internal control is more useful for creating framework projects as opposed to app modules.

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: create a class, build and run a project, and use the debugger.

Create 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 subjects 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 launch screen as shown in Figure 1-3. Select Create a new Xcode Project (see Figure 1-3). Alternatively, you may do the same by selecting File image Project... from the Xcode menu bar.
  2. Choose OS X image Application image Command Line Tool as shown in the Choose a template for your new project screen (see Figure 2-1).

    9781484204375_Fig02-01.jpg

    Figure 2-1. Choosing an Xcode template

  3. Follow the same on-screen instruction that you used to create the LessonOne project (see Chapter 1, “Create an iOS Project Using the Template”) to finish creating the new project with the template:
    1. Product Name: HelloSwift
    2. Organization Name: for example, PdaChoice
    3. Organization Identifier: for example, com.liaollc
    4. Language: Swift
    5. Click the Next button when done.
    6. Select a folder in which to save your HelloSwift project.

    The HelloSwift project appears in the Project Navigator area (see Figure 2-2).

    9781484204375_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 program, just like the main(...) in Java. 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 Eclipse Project Explorer, this is where you can see the whole project structure and select the file that 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 Source Editor area in the middle shows the selected file in its editor, in which you can edit the file, writing your code or modifying 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 edit attributes of the whole file or the item selected in the Source Editor. 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 Libraries. 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 Object Library a lot to compose UIs visually.

    Click on 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 Eclipse, but essentially Xcode 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.

    Create a Swift Class

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

  4. 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. Choose iOS image Source from the left panel and select Swift File from the right panel 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.

    9781484204375_Fig02-03.jpg

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

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

    Listing 2-1. Declare MobileDeveloper Class

    class MobileDeveloper {

    }

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

  6. 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 is String inferred by the value
    }

    Note  Semicolon (;) is optional for terminating a statement.

Create a Swift Protocol

JAVA ANALOGY

The Java interface defines object obligations.

In object-oriented programming (OOP), it is important to define a set of behaviors that are expected of certain objects. In Java, you declare an interface; in Swift, you declare a protocol.

Create a Swift protocol called Programmer by doing the following:

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

    Listing 2-3. Declare the Programmer Protocol

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

Implement the Protocol

JAVA ANALOGY

Implement a Java interface.

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.

Use the Swift Instance

JAVA ANALOGY

Programmer you = new MobileDeveloper();
you.setName("You");
you.writeCode("Java");

You have created a Swift MobileDeveloper class and implemented the Programmer obligations, in pretty much the same way you normally do in Java except with 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");

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 on the line number in the Xcode code editor. Figure 2-4 depicts a breakpoint that was set in the main.swift file.

    9781484204375_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 (e.g., 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 z+R (see Figure 2-5).

    9781484204375_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 debug toolbar, Variable, and Console views.
    3. Hide the Utility Area.

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

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

More About the Swift Language

A lot of Java syntax and conventional coding approaches would work just fine in Swift. However, Swift does have some pretty neat features of its own, 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 depicts the Playground: you write code in the left panel and the right panel renders the result immediately.

9781484204375_Fig02-06.jpg

Figure 2-6. Xcode Playground

JAVA ANALOGY

Java scratchpad.

Variables and Constants

You declare a variable using the var keyword, and you use let to declare constants. While Java variables are always defined within the enclosing brackets, Swift variables are global if defined not within enclosing brackets. The following code snippet (see Listing 2-7) depicts usage of Swift variables:

Listing 2-7. Common variables usages

var GlobalVar : String = "Global Variable"; // global scope

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

Both Java and Swift are type-safe languages. Any variable must be declared with a type; the compiler will help flag any mismatched types. In Swift, if the type can be inferred by its value, you don’t need to explicitly declare the type. Listing 2-8 is essentially exactly the same as Listing 2-7. The Swift type inference feature encourages developers to assign initial values that reduce the common errors from uninitialized data.

Listing 2-8. 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 optional type. This indicates the value it contains may be absent (nil, equivalent to null in Java) for the intended type. For example, Listing 2-9 depicts the difference in Swift and Java for converting a string to an integer.

Listing 2-9. Optional Type in Swift vs. Handle Exception in Java

////// Java NumberFormatException
String intStr = "123"; // or "xYz"
int myInt;
try {
  myInt = Integer.parseInt("234");
} catch (NumberFormatException e) {
  myInt = Integer.MAX_VALUE;
}

////// 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-10 demonstrates two practical Swift optional usages:

  • Forced Unwrapping, which uses a postfixed exclamation pointer (!)
  • Optional Binding

Listing 2-10. 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 Implicitly Unwrapped Optional postfixed with ! instead of ?. For example: var delegate: MyDelegate!

Any of the Optionals usages described earlier are applicable here. You treat it as Optionals but you don’t need to force unwrapping it. You commonly see this usage in the iOS framework for properties that are initialized somewhere else (i.e., 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

Tuples group multiple values into a single compound value. This seems to have been the useful feature that Java developers (as well as those using C#, Objective-C, C/C++, etc.) have been looking for. For example, you can pass or return a value without creating a class or a struct (structs are also supported in Swift). Listing 2-11 shows the most common tuple usages.

Listing 2-11. 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

JAVA ANALOGY

java.lang.ArrayList and HashMap.

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

  • Initialization
  • Access and modify elements using subscript syntax
  • Common collection APIs

Listing 2-12. 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)")

Constant Dictionary or Array is immutable, meaning it is not allowed to add or remove elements, nor modify existing items. On the other hand, variable Dictionary or Array is mutable.

Control Flow

Similar to Java, 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-13 demonstrates the following common control flow usages:

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

Listing 2-13. 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-14 shows the following improved control flow switch usages in Swift:

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

Listing 2-14. 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-15 demonstrates both value bindings.

Listing 2-15. Temporary Value Binding and Using 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 enum to define a common type for a group of related values. After the enumeration is defined, you use it just as a Swift type that is type safe. Listing 2-16 shows the following common enum usages:

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

Listing 2-16. 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 Java methods, the parameter and return type are declared after the type name. Here are the typical Swift function usages you most likely will encounter (see Listing 2-17):

  • 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: Variable length of the method parameters without using Array type.
  • Function parameters are constant by default—this is different from Java rules.
  • Swift Functions 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 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. 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-17. 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

Swift classes contain similar elements to Java classes. The simplest Java-like class form can be depicted as shown in Listing 2-18.

Listing 2-18. Simple Java-Like Swift Class

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

Property

Java fields can be mapped to Swift properties as shown previously in Listing 2-18; they are called stored properties. In Swift, properties can do more than Java fields. Listing 2-19 demonstrates the following Swift property usages:

  • Stored property: Java field.
  • Computed property: For derived values.
  • Property observer: Optional coding block that responds to changes in a property value.
  • Type property: Similar to a Java class variable, but the stored type property is 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-19. 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 be set from (oldValue)")
    }
  }

  // Swift class Type property,
  class var MyComputedTypeProperty : String {
    return "Only computed Type property is supported"
  }

  // use inner 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 (i.e., a class). They are still functions as described previously (see Listing 2-17). You can define instance methods or class methods just as Java does. Listing 2-20 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 static func to declare type methods in struct or enum types.

Listing 2-20. Common Method Usages

class MyClass {

///////// methods copied from Listing 2-17 //////////
  func doWork(parm : String) -> String { // just like func
    return "TODO: " + parm
  }

  // default parm value, always imply externl parm name
  func doWork2(name: String = "Swift") -> String {
    return "TODO: " + name
  }

  // func is a type, can be used for parm or return type, etc.
  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, aka Java class static method
  class func DoWork(parm : String) -> String {
    return "TODO: (Just like Java class static method)" + 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 Java, 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:

  • Similar to Java, your custom classes are reference types. Primitives, structs, and enums are value types.
  • Unlike Java, some of the frequently used data types are value types, including String, Dictionary and Array (they are not classes in Swift). This is very 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 Foundation 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 non-code 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 translate a simple HelloMobile ADT project to Xcode so that you can visualize these software artifacts in a typical iOS app. The Android app in Figure 2-7 was created using the ADT Create Android Project template:

  • It only has one screen: one Java Fragment class and one layout file.
  • On this screen, it has an EditText to take user input. When the Hello... button is pressed, it shows a greeting on a TextView.

9781484204375_Fig02-07.jpg

Figure 2-7. HelloMobile, Android version

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

  1. Select Create a new Xcode project (See Figure 1-3) from 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, then choose Single View Application as the project template (see Figure 2-8).

    9781484204375_Fig02-08.jpg

    Figure 2-8. Single View Application template

  3. Complete the following fields to finish the new-project creation:
    1. Product Name: HelloMobile
    2. Organization Name: for example, PdaChoice
    3. Organization Identifier: for example, com.liaollc
    4. Language: Swift
    5. Click the Next button when done.
    6. 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-9).

9781484204375_Fig02-09.jpg

Figure 2-9. 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:

    a.    AppDelegate.swift: Each iOS app must have one AppDelegate class. Similar to android.app.Application, you don’t need to modify this file if your program doesn’t need to track the global application state.

    b.    ViewController.swift: There is a ViewController class paired with the content view. The intended purpose is the same as the Android Fragment class in an Android project: the content view controller for the content view.

  • Main.storyboard file with .storyboard file extension:

    a.    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.

  • Images.xcassets. This is where you put your image assets, in what is called the assets catalog:

    b.    Developers should provide different assets for each device configuration. This is done for the same purpose as providing alternative resources in Android.

    a.    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:

    a.    The best Android analogy is the AndroidManifest.xml file, but not exactly. 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.

  • Unlike ADT projects that must follow the ADT project-folder structure, you can organize your project structure any way you want. For example, normally I manually create Java-package-like folders to organize my Swift classes and create a res folder to organize any resources files, including the Images.xcassets.

    a.    In Xcode, the folder can be a actual folder of a light-blue color (e.g., the Images.xcassets folder).

    b.    Folders in Xcode can also be just a tag, called a group, with a yellow color (e.g., HelloMobile, Supporting Files, etc.). 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 very 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 (see Figure 2-9). The Project Settings editor shows in the Editor area:

    a.    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

ANDROID ANALOGY

There is no storyboard-like feature in ADT. You use the Graphic Layout Editor to create one content view in one layout file at a time.

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 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 the 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 tool bar. All of them are important; you should take a moment to get familiar with them (see Figure 2-10):

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

9781484204375_Fig02-10.jpg

Figure 2-10. Select UI components from Object Library

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

First you will Implement the user interface of the HelloMobile iOS app. Xcode storyboard provides everything you need for this mission.

Object Library and Attributes Inspector

ANDROID ANALOGY

Drag and drop the UI widgets from Palette View in the ADT Graphical Layout Editor and set the widget attributes in the layout file.

You need to add three UI widgets to the content view, just as in the counterpart Android app, 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 Navigator and Debug areas by selecting the toggle buttons, as indicated in Figure 2-10.
  4. I will talk about size class, an important new iOS 8 feature, in Chapter 3. For now, disable it: uncheck Use Size Classes in the File Inspector of the Utility area, as shown in Figure 2-11. This will give you a better WYSIWYG storyboard editor.

    9781484204375_Fig02-11.jpg

    Figure 2-11. Disable Size Classes in File Inspector

  5. To add the UI widget to storyboard scene, find the desired UI widget from 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 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 very 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 as many characters as needed.

      Tip  The iOS widgets you need are called TextField, Label, and Button.

    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-12).

      9781484204375_Fig02-12.jpg

      Figure 2-12. Guide lines

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

      9781484204375_Fig02-13.jpg

      Figure 2-13. Three simple UI widgets

  6. Just as in Android, the attributes of UI widgets in Swift affect 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. To make the TextField like the Android counterpart, modify the following attributes:
    1. Font size: System 24
    2. Placeholder (a.k.a. android:hint): "
      Enter a Name, e.g., You"
    3. Alignment: 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 Android EditText.
    5. Switch to 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. Text: for example, "Hello World!"
    2. Font: for example, System 20 or Headline
    3. Alignment: center
    4. Lines: 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, select the Assistant Editor button on the toolbar and select Preview in the Assistant Editor, as shown in Figure 2-14.

    9781484204375_Fig02-14.jpg

    Figure 2-14. Three simple widgets added to storyboard

The look and feel in portrait mode is close enough for our purposes: 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 of the Xcode storyboard editor. The Xcode workspace seems quite different from Eclipse. Spend a moment to get familiar with the Xcode workspace, including the storyboard editor, the Utility area, selector tool bar, and so forth. Xcode storyboarding is a very important tool that will greatly influence your productivity when creating iOS apps.

Summary

On the surface, you actually learned about a lot of things in this chapter. You started with a discussion of Swift–Java language comparisons to learn their similarities, then you 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 new 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 so you can visualize. You also got your first taste of the Xcode storyboard, which is very 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