Page 1

Programming A Wiley Sampler

JAVASCRIPT &JQUERY

interactive front-end web development

JON DUCKETT

Wiley is a registered trademark of John Wiley & Sons, Inc.


1. Beginning iOS Programming: Building and Deploying iOS Applications Nick Harris................................................................................................................................Page 3

2. JavaScript & jQuery: Interactive Front-End Web Development Jon Duckett...............................................................................................................................Page 51

3. Professional ASP.NET MVC 5 Jon Galloway, Brad Wilson, K. Scott Allen & David Matson........................................Page 95

4. Professional Microsoft SQL Server 2014 Integration Services Brian Knight, Kevin Knight, Jessica M. Moss, Mike David & Chris Rock...................Page 136


Contents

Introduction Chapter 1: Building a Real-World iOS App: Bands

Introducing Bands Getting Started Scoping the App Defining the Features Creating a Development Plan

xix 1

2 3 4 5 6

Summary 6 Chapter 2: Introduction to Objective-C

Exploring the History of Objective-C Explaining the Basics Learning About Objects and Classes Instantiating Objects Managing Memory Introducing Automatic Reference Counting Adding Properties to a Class Explaining Strings Using Basic Data Structures

Discussing Advanced Concepts Explaining the Model-View-Controller Design Pattern Learning About Protocols and Delegates Using Blocks Handling Errors

9

9 10 12 16 22 26 27 32 35

39 39 41 44 44

Summary 47 Chapter 3: Starting a New App

Creating a New App in Xcode Discussing Xcode Templates Learning About Bundle Identifiers Exploring the Xcode Project Layout Discussing the UIKit Framework Discussing the Main Storyboard

Adding a Label to a Storyboard

ftoc.indd 13

51

51 54 54 55 56 56

56

1/25/2014 5:54:41 PM


CONTENTS

Exploring Interface Builder Setting Attributes Exploring the Inspectors Aligning UI Objects

Running in the Simulator Choosing a Device Learning to Test on All Device Sizes

Learning About Auto Layout Discussing Auto Layout Basics Testing Rotation

Exploring Application Settings Setting Version and Build Numbers Setting Supported Rotation Orientations Setting the App Icon Setting Launch Images

57 58 59 59

59 60 61

62 64 64

66 66 67 68 70

Running on a Device 71 Summary 72 Chapter 4: Creating a User Input Form

Introducing the Band Model Object Creating the Band Model Object Creating Enumerations Adding Properties to the Band Model Object

Building an Interactive User Interface Learning About IBOutlet Using UITextField and UITextFieldDelegate Using UITextView and UITextViewDelegate Using UIButton and IBAction Using UIStepper Using UISegmentedControl Using UISwitch

Saving and Retrieving Data Implementing the NSCoding Protocol Saving Data Retrieving Saved Data Deleting Saved Data

75

75 76 77 78

79 79 81 84 85 87 89 90

91 91 93 95 97

Summary 100

xiv

ftoc.indd 14

1/25/2014 5:54:41 PM


CONTENTS

Chapter 5: Using Table Views

Exploring Table Views Learning About Tables Learning About Cells

Implementing the Bands Data Source Creating the Band Storage Adding Bands Displaying Bands

Implementing Sections and Index Adding Section Headers Showing the Section Index

Editing Table Data Enabling Edit Mode Deleting Cells and Data Modifying Data

103

104 104 107

110 110 113 119

121 122 122

123 124 125 126

Summary 130 Chapter 6: Integrating the Camera and Photo Library in iOS Apps

133

Adding an Image View and Gesture Recognizer

134

Enabling User Interactions with a UIImageView Learning About Gesture Recognizers

134 136

Selecting a Picture from the Photo Library

139

Learning About UIImagePickerController Determining Device Capabilities Allowing Picture Editing Saving Band Images Deleting Band Images

140 140 141 143 145

Taking a Picture with the Camera 147 Summary 150 Chapter 7: Integrating Social Media

Sending E-mails and Text Messages Using the E-mail Composer Using the Message Composer

153

154 154 160

Simplifying Social Network Integration

163

Introducing the Activity View Controller

164

xv

ftoc.indd 15

1/25/2014 5:54:41 PM


CONTENTS

Learning About Twitter Integration Learning About Facebook Integration Learning About Flickr Integration Limiting Sharing Options

167 168 169 170

Summary 172 Chapter 8: Using Web Views

175

Learning About Web Views

175

Loading a URL Loading a URL That Contains Special Characters Showing User Feedback

180 182 183

Adding Navigation

186

Creating a Toolbar Opening Safari

186 191

Summary 193 Chapter 9: Exploring Maps and Local Search

195

Learning About Map Views

196

Getting the User’s Location Changing the Map Type

198 201

Performing a Local Search Animating Annotations Interacting with Annotations

203 209 211

Summary 215 Chapter 10: Getting Started with Web Services

Learning About Web Services Exploring the iTunes Search API Discussing JSON Adding the Search View

Introducing NSURLSession Creating and Scheduling a Data Task Parsing JSON

Displaying Search Results Previewing Tracks Showing Tracks in iTunes

219

220 220 221 223

227 227 231

233 236 239

Summary 240

xvi

ftoc.indd 16

1/25/2014 5:54:41 PM


CONTENTS

Chapter 11: Creating a Universal App

Transitioning to a Universal App Supporting Rotation Using Auto Layout

Learning About Popovers Presenting Action Sheets in Popovers Using the UIPopoverController

243

244 249

250 250 252

Finishing the iPad Implementation 258 Summary 265 Chapter 12: Deploying Your iOS App

Deploying the App to Beta Testers Registering Beta Devices Generating Digital Certificates Creating an App ID and Ad Hoc Provisioning Profile Signing and Deploying an Ad Hoc Build

Submitting the App to Apple Exploring iTunes Connect Creating an App Store Provisioning Profile Validating and Submitting an App

267

268 269 271 274 276

280 280 283 284

Summary 285 Appendix: Answers to Exercises

287

Index

293

xvii

ftoc.indd 17

1/25/2014 5:54:42 PM


2

Introduction to Objective-C What you will learn in this chapter: ➤➤

An overview of Objective-C

➤➤

Declaring classes and instancing objects

➤➤

Memory management in Objective-C

➤➤

The Model-View-Controller design pattern

➤➤

Delegates and protocols in Objective-C

➤➤

Overview of blocks

➤➤

Error handling patterns in Objective-C

The first step to creating the Bands app is to learn about the language it will be written in, Objective-C. Objective-C is the programming language used to develop both Mac and iOS applications. It’s a compiled language, meaning that it gets compiled down to raw machine code as opposed to being interpreted at runtime. As its name implies, it’s based on the C programming language. It’s actually a superset of C that adds object-oriented programming methodologies. Because it’s a descendant of C, its syntax and concepts are similar to other C-based languages. In this chapter you learn the basics of Objective-C by comparing it to Java and C#.

Exploring the History of Objective-C Objective-C was developed in the early 1980s by a company called Stepstone. It was working on a legacy system built using C but wanted to add reusability to the code base by using objects and messaging. The concept of object-oriented programming (OOP) had been around for a while. The Smalltalk language developed by Xerox was the most prominent objectoriented language in use at the time. Objective-C got its start by taking some of the concepts and syntax of Smalltalk and adding it to C. This can be seen in the syntax of message passing in Objective-C and Smalltalk.

c02.indd 9

1/25/2014 4:52:39 PM


10 

❘  CHAPTER 2  Introduction to Objective-C

Message passing is another way of saying method calling. In OOP languages an object can send a message to or call a method of another object. All object-oriented languages include this. Listing 2-1 shows how message passing is done in Smalltalk, Objective-C, Java, and C#. Listing 2-1:  Message Passing in Different Languages

Smalltalk: anObject aMessage: aParameter secondParameter: bParameter Objective-C: [anObject aMessage:aParameter secondParameter:bParameter]; Java and C#: anObject.aMessage(aParameter, bParameter);

Objective-C got its foothold in mainstream programming when it was licensed by NeXT in the late 1980s. NeXT was a computer company founded by Steve Jobs after he was forced from Apple. It manufactured workstations for universities and big businesses. The workstations ran its proprietary operating system called NeXTSTEP, which used Objective-C as its programming language and runtime. This was different than other workstations sold at the time that ran the UNIX operating system based on the C language. NeXT was eventually acquired by Apple, bringing Steve Jobs back to the original company he founded. The acquisition also brought the NeXTSTEP operating system, which became the basis for OS X and the Cocoa API used to create Mac applications. The Cocoa API was then expanded to Cocoa Touch, which is the API, frameworks, and user interface libraries used to create iOS applications.

Explaining the Basics Primitive types in every programming language are the basic types used to build more complex objects and data structures. They are typically the same from language to language. The primitive types in Objective-C are the same as those in C and most C variants. Table 2-1 lists these types. Table 2-1:  Primitive Data Types in Objective-C

c02.indd 10

Data T ype

Description

bool

Single byte representing TRUE/FALSE or YES/NO

char

Integer value the size of 1 byte

short

Integer value the size of 2 bytes

int

Integer value the size of 4 bytes

long

Integer value the size of 8 bytes

float

Single precision floating-point type the size of 4 bytes

double

Double precision floating-point type the size of 8 bytes

1/25/2014 4:52:39 PM


Explaining the Basics 

❘  11

As with C and C++, Objective-C includes the typedef keyword. If you are coming from C# or Java and have never programmed using C or C++, you may not be familiar with typedef. It gives you a way of creating and naming a new data type using primitive data types. You can then refer to this new data type by the name you assigned it anywhere in your code. Listing 2-2 shows a simple yet silly example of typedef that creates a new data type called myInt, which is the same as the primitive int data type that can then be used the same as int throughout the code. Listing 2-2:  typedef Example in Objective-C

// Objective C typedef int myInt; myInt variableOne = 5; myInt variableTwo = 10; myInt variableThree = variableOne + variableTwo; // variableThree == 15;

A typical use of typedef in Objective-C is naming a declared enumerated type. An enumerated type, or enum, is a primitive type that is made up of a set of constants. Each constant is represented by an integer. They are used in pretty much every OOP language, including Java and C#. They give you a way to declare a variable with the enumerations name and assign its value using the constant names. It helps to make your code easier to read. The four cardinal directions are often declared as an enumeration. To use an enum in C, you would need to add the enum keyword before its name. Instead of this you can typedef it, so you no longer need the enum keyword. You don’t have to do this, but it’s a common practice. Another common practice in Objective-C is to prepend the constants with the name of the enumeration. Again, you don’t have to do, this but it helps the readability of your code. Listing 2-3 demonstrates how you declare and typedef an enum in Objective-C as well as Java and C# (their syntax is identical) and how you would use it later in code. Listing 2-3:  Declaring Enumerations

// Objective C typedef enum { CardinalDirectionNorth, CardinalDirectionSouth, CardinalDirectionEast, CardinalDirectionWest } CardinalDirection; CardinalDirection windDirection = CardinalDirectionNorth; if(windDirection == CardinalDirectionNorth) // the wind is blowing north // Java and C# public enum CardinalDirection { NORTH,

continues

c02.indd 11

1/25/2014 4:52:39 PM


12 

❘  CHAPTER 2  Introduction to Objective-C

Listing 2-3  (continued)

SOUTH, EAST, WEST } CardinalDirection windDirection = CardinalDirectionNorth; if(windDirection == NORTH) // the wind is blowing north

In C, C++, C#, and Objective-C, you can also create a struct. Java does not have this because everything is a class. A struct is not a class. A struct is a compound data type made up of primitive data types. It’s a way of encapsulating similar data. Similar to enums, they often use typedef to avoid having to use the keyword structs when using them in code. There are three common structs you use in Objective-C: CGPoint, CGSize, and CGRect. Listing 2-4 shows how these structs are defined. Listing 2-4:  Common Structs in Objective-C

struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CGPoint CGPoint; struct CGSize { CGFloat width; CGFloat height; }; typedef struct CGSize CGSize; struct CGRect { CGPoint origin; CGSize size; }; typedef struct CGRect CGRect;

Learning About Objects and Classes Objects in Objective-C, as in any other object-oriented language, are the building blocks of the application. They have member variables that describe the object and methods that can manipulate the member variables, as well as any parameters that may be passed to them. Member variables can be public or private. Objects are defined in a class. The class acts as the template for how an object is created and behaves. A class in Objective-C consists of two files much like classes in C++. The header file (.h) contains the interface of the class. This is where you declare the member variables and the method signatures. The implementation file (.m) is where you write the code for the actual methods. Listings 2-5 and 2-6 show how to define a class and its implementation in Java and C#, respectively. Listing 2-7 shows

c02.indd 12

1/25/2014 4:52:39 PM


Explaining the Basics 

❘  13

how you declare a header file in Objective-C, while Listing 2-8 show how you define the implementation file. If you are an expert developer of either language, forgive some of the bad practices in these examples. Listing 2-5:  Defining a Class in Java

package SamplePackage; public class SimpleClass { public int firstInt; public int secondInt; public int sum() { return firstInt + secondInt; } public int sum(int thirdInt, int fourthInt) { return firstInt + secondInt + thirdInt + fourthInt; } private int sub() { return firstInt – secondInt; } }

Listing 2-6:  Defining a Class in C#

namespace SampleNameSpace { public class SimpleClass { public int FirstInt; public int SecondInt; public int Sum() { return FirstInt + SecondInt; } public in Sum(int thirdInt, int fourthInt) { return FirstInt + SecondInt + thirdInt + fourthInt; } private int Sub() { return FirstInt – SecondInt; } } }

c02.indd 13

1/25/2014 4:52:40 PM


14 

❘  CHAPTER 2  Introduction to Objective-C

Listing 2-7:  Defining a Class Interface in Objective-C

@interface SimpleClass : NSObject { @public int firstInt; int secondInt; } - (int)sum; - (int)sumWithThirdInt:(int)thirdInt fourthInt:(int)fourthInt; @end

Listing 2-8:  Defining a Class Implementation in Objective-C

#import "SimpleClass.h" @implementation SimpleClass - (int)sum { return firstInt + secondInt; } - (int)sumWithThirdInt:(int)thirdInt fourthInt:(int)fourthInt { return firstInt + secondInt + thirdInt + fourthInt; } - (int)sub { return firstInt – secondInt; } @end

Note  The @ symbol is special in Objective-C. It has no meaning in C. Because Objective-C is a superset of C, a C compiler can be modified to also compile Objective-C. The @ symbol tells the compiler when to start and stop using the Objective-C compiler versus the straight C compiler.

All three of these classes are conceptually the same. They all have two integer member variables that are public, a public method that adds together the member variables, a public method that adds the member variables plus an additional two integers passed in as a parameters, and a private method

c02.indd 14

1/25/2014 4:52:40 PM


Explaining the Basics 

❘  15

that subtracts Y from X. The following sections discuss the key differences between classes in Java and C# compared to Objective-C.

There Are No Namespaces in Objective-C The first difference is the package and namespace keywords in the Java and C# code that do not correspond to anything in the Objective-C code. This is because Objective-C does not have the concept of namespaces. A namespace is a way of grouping related classes together. C# uses namespace as the keyword for this concept, whereas Java uses packages to accomplish the same thing. If a class in a different namespace wants to use a class in another, it needs to link to the namespace or package the other class is in. In Java this is done using the import keyword followed by the name of the package. In C# this is done with the using keyword. The class must also be declared as public, which you should note the SampleClass in both the Java and C# examples are. In Objective-C a class is made visible to another class simply by importing the header file in which the classes interface is declared. The public keyword is also used to declare if member variables are visible to other classes. All three examples declare their member variables to be public; however, this is not a common practice in modern Objective-C, as you will learn in the Adding Properties to a Class section of this chapter.

In Objective-C, Methods Are Visible to Other Classes Methods in a Java or C# class can also be declared public, making them visible to other objects. This is not the case with Objective-C. In Objective-C all methods that are declared in the interface are visible to other classes. If a class needs a private method, it just adds the method to the implementation. All code within the implementation can call that method, but it will not be visible to any classes that import the header file.

In Objective-C, Most Classes Inherit from NSObject Another key concept of object-oriented languages is the capability of one class to inherit from another. In Java all classes inherit from the Object class. C# is similar with the System.Object class. In Objective-C virtually every class inherits from NSObject. The reason all three languages have a common root class is to provide methods and behaviors that can be assumed as members. In Objective-C the code for managing the memory of an object is all defined in NSObject. The difference in the syntax is that in Java and C# classes that do not explicitly define their superclass, the root class is assumed. In Objective-C you must always declare the superclass by following the name of the class with a colon and then the name of the superclass, as shown in the example @interface SimpleClass : NSObject.

Objective-C Uses Long and Explicit Signatures The last difference you notice is the signatures of the methods themselves. Java and C# both use the same type of method signatures. The return type of the method is listed first, followed by its name

c02.indd 15

1/25/2014 4:52:40 PM


16 

❘  CHAPTER 2  Introduction to Objective-C

and then by any parameters and their type listed within parentheses. They also use method overloading where the same method name is used but is distinguished as different by the list of parameters. In Objective-C the signature is a bit different, which reflects its roots in Smalltalk. Objective-C method signatures tend to be very long and explicit. Many developers coming from other languages may dislike this at first but learn to love it as it enhances the readability of the code. Instead of needing to know which method of “Sum” to use when you want to pass in two parameters, you know by just looking that the sumWithThirdInt:fourthInt: method is the one you want. Actually that is the full name of that method. The colons in the method name denote the number of parameters the method takes. By having the parameters listed inline with the method name, you can create signatures that are easier to understand. As you proceed through this book, you will see how this type of method signature is used throughout Objective-C and Cocoa Touch.

Instantiating Objects Classes are only the template for creating objects. To use an object it needs to be instantiated and created in memory. In Java and C# you use the new keyword and a constructor. Both languages have a default constructor that is part of their base object class. Listing 2-9 shows how you do this in either Java or C#. Listing 2-9:  Instantiating an Object in Java or C#

SimpleClass simpleClassInstance = new SimpleClass();

In Objective-C the NSObject class has something similar to a default constructor but slightly different. Instead of one step to instantiate an object, you do it in two steps. The first step uses the static method alloc, which finds enough available memory to hold the object and assign it. The second step uses the init method to set the memory. Listing 2-10 shows an example. Listing 2-10:  Instantiating an Object in Objective-C

SimpleClass *simpleClassInstance = [[SimpleClass alloc] init];

If you have ever written code in C or C++, you should recognize the * operator. This is the pointer dereference operator. It acts the same in Objective-C by dereferencing the pointer and getting or setting the object in memory. Pointers are part of C. The memory of a computer can be thought of as a bunch of little boxes that hold values. Each of these boxes has an address. In this example the variable simpleClassInstance is a pointer. The value it holds in memory is not the object but instead the address of where the object exists in memory. It “points” to the object in another part of the memory. Figure 2-1 illustrates how this works.

c02.indd 16

1/25/2014 4:52:40 PM


Explaining the Basics 

❘  17

0x000F

0x000E

0x000D

0x000C

0x000B

0x000A

0x0009

0x0008

0x0007

0x0006

0x0005

0x0004

0x0003

0x0002

SimpleClass Object

simpleClassInstance

0x0001

0x0008

Points to the Object

Figure 2-1

In Java and C# you can also declare your own constructors that can take a list of parameters and set the member variables of the object. Listings 2-11 and 2-12 add these constructors to the Java and C# example classes with sample code of how they are called. Listing 2-11:  Defining a Constructor in Java

package SamplePackage; public class SimpleClass { public int firstInt; public int secondInt; public SimpleClass(int initialFirstInt, int initialSecondInt) { firstInt = initialFirstInt; secondInt = initialSecondInt; } // other methods discussed eariler } // sample code to create a new instance SimpleClass aSimpleClassInstance = new SimpleClass(1, 2);

c02.indd 17

1/25/2014 4:52:41 PM


18 

❘  CHAPTER 2  Introduction to Objective-C

Listing 2-12:  Defining a Constructor in C#

namespace SampleNameSpace { public class SimpleClass { public int FirstInt; public int SecondInt; public SimpleClass(int firstInt, int secondInt) { FirstInt = firstInt; SecondInt = secondInt; } // other methods discussed earlier } } // sample code to create a new instance SimpleClass aSimpleClassInstance = new SimpleClass(1, 2);

To implement the same type of constructor in Objective-C, you would add your own init method, as shown in Listing 2-13. Listing 2-13:  Instantiating Objects in Objective-C

// in the SimpleClass.h file @interface SimpleClass : NSObject { @public int firstInt; int secondInt; } - (id)initWithFirstInt:(int)firstIntValue secondInt:(int)secondIntValue; // other methods discussed earlier @end // in the SimpleClass.m file @implementation SimpleClass - (id)initWithFirstInt:(int)firstIntValue secondInt:(int)secondIntValue { self = [super init]; if(!self) return nil; firstInt = firstIntValue; secondInt = secondIntValue; return self;

c02.indd 18

1/25/2014 4:52:41 PM


Explaining the Basics 

❘  19

} // other methods discussed earlier @end // sample code to create a new instance SimpleClass *aSimpleClassInstance = [[SimpleClass alloc] initWithFirstInt:1 secondInt:2];

There are a few things to discuss in this code sample. The first is the use of id type. Objective-C is a dynamic language, meaning that you do not have to give a specific type to an object at compile time. The id type can hold a pointer to any object. It is similar to the dynamic type in C#. Java does not have anything similar. When you use the id type, its actual type is determined at runtime. Returning id from an init method is part of a Cocoa convention, which you should always follow. The next is the use of self. The self variable is the same in Java or this in C#. It refers to the instance of the object that is receiving the message. When you are initializing an object, you first want to call init on its parent class. This ensures that objects are created correctly through their hierarchy.

0x000F

0x000E

0x000D

0x000C

0x000B

0x000A

0x0009

0x0008

0x0007

0x0006

0x0005

0x0004

0x0003

0x0002

simpleClassInstance

0x0001

0x0000

The if statement, if(!self), introduces another concept that is prevalent throughout Objective-C. If a variable does not point to anything, it has a value of nil. The nil value is essentially 0. Figure 2-2 illustrates how this works.

Figure 2-2

In C the value 0 is synonymous with FALSE, while any value greater than 0 is synonymous with TRUE. If an object has failed to initialize, then its pointer will be nil. The reason you need to check if the parent class returned nil is defensive coding. If a pointer is nil and you send it a message, it is treated as a no op, meaning nothing will happen. In Java and C# this throws an exception.

c02.indd 19

1/25/2014 4:52:42 PM


20 

❘  CHAPTER 2  Introduction to Objective-C

The rest of the init method works the same as the constructors in Java and C#. The member variables are set using the values passed in before returning the pointer. Note  The NSObject class also has a new method. It performs both the alloc and init method calls and then returns the pointer. Using it means any overridden init methods that take parameters will not be called. Instead you need to set the values of the member variables after the object is instantiated.

Another approach to instantiating objects is to use a factory method. These methods are static methods. A static method does not need an instance of the class to call it. It also does not have access to any of the member variables of a class. If you have written code in Java or C#, you are familiar with static methods and factory methods. In Objective-C they are more of a convenience method than anything else, which is different from their use in Java and C#. The basic idea remains the same, though. Listings 2-14 and 2-15 show how you would implement a factory constructor in Java or C#, whereas Listing 2-16 demonstrates the same in Objective-C. These types of convenience methods are used often in many of the basic data structures of Objective-C, which are discussed in the Using Basic Data Structures section of this chapter. Listing 2-14:  Defining a Factory Method in Java

package SamplePackage; public class SimpleClass { public int firstInt; public int secondInt; public static SimpleClass Create(int initialFirstInt, int initialSecondInt) { SimpleClass simpleClass = new SimpleClass(); simpleClass.firstInt = initialFirstInt; simpleClass.secondInt = initialSecondInt; return simpleClass; } // other methods discussed eariler } // sample code to create a new instance SimpleClass aSimpleClassInstance = SimpleClass.Create(1, 2);

Listing 2-15:  Defining a Factory Method in C#

namespace SampleNameSpace { public class SimpleClass { public int FirstInt;

c02.indd 20

1/25/2014 4:52:42 PM


Explaining the Basics 

❘  21

public int SecondInt; public static SimpleClass Create(int firstInt, int secondInt) { SimpleClass simpleClass = new SimpleClass(); simpleClass.FirstInt = firstInt; simpleClass.SecondInt = secondInt; return simpleClass; } // other methods discussed earlier } } // sample code to create a new instance SimpleClass aSimpleClassInstance = SimpleClass.Create(1, 2);

Listing 2-16:  Defining a Factory Method in Objective-C

// in the SimpleClass.h file @interface SimpleClass : NSObject { @public int firstInt; int secondInt; } + (id)simpleClassWithFirstInt:(int)firstIntValue secondInt:(int)secondIntValue; // other methods discussed earlier @end // in the SimpleClass.m file @implementation SimpleClass + (id)simpleClassWithFirstInt:(int)firstIntValue secondInt:(int)secondIntValue { SimpleClass *simpleClass = [[SimpleClass alloc] init]; simpleClass->firstInt = firstIntValue; simpleClass->secondInt = secondIntValue; return simpleClass; } // other methods discussed earlier @end // sample code to create a new instance SimpleClass *aSimpleClassInstance = [SimpleClass simpleClassWithFirstInt:1 secondInt:2];

c02.indd 21

1/25/2014 4:52:42 PM


22 

❘  CHAPTER 2  Introduction to Objective-C

The Java and C# implementations rely on the default constructors defined in their respective root classes to insatiate a new object. This is the same as the init method defined in the NSObject class. They next set the member variables of the new instance before returning it. Syntactically, the difference is how a method is declared as static. In Java and C# the static keyword is added to the method signature. In Objective-C a static method is declared by using the + (plus) symbol instead of the – (minus) symbol that would define it as an instance method.

Managing Memory Memory management is important in Objective-C. Memory is a finite resource, meaning there is only so much of it that can be used. This is particularly true on mobile devices. When a system runs out of memory, it can no longer perform any more instructions, which is obviously a bad thing. Running low on memory will also have a dramatic impact on performance. The system has to spend a lot more time finding available memory to use, which slows down every process. Memory management is controlling what objects need to remain in memory and which ones are no longer in use, so their memory can be reused. Memory leaks are a classic problem in computer programming. A memory leak, in the most basic of definitions, is when memory is allocated but never deallocated. The opposite of a leak is when memory is deallocated before it is done being used. This is what has been historically referred to as a dangling pointer. In Objective-C it’s common to refer to these as zombie objects. These types of memory issues are usually easier to find because the program will most likely crash if it tries to use a deallocated object. Languages and runtimes handle memory management in two difference ways. Java and C# use garbage collection. It was first introduced in Lisp in the late 1950s. The implementation of garbage collection is detailed and different depending on the runtime, but the idea is basically the same. As a program executes it allocates objects in memory that it needs to continue. Periodically another process runs that looks for objects that are no longer reachable, meaning they have no references left to them in any code that is executing. This type of system works very well; though contrary to popular belief your code can still leak memory by creating objects and keeping a reference to them but never using them again. This system also has a bit of overhead associated with it. The system needs to continue executing the program being used while running the garbage collection process in parallel. This can create performance problems on systems that have limited computational power. Objective-C on iOS does not use garbage collection. Instead it uses manual reference counting. Each object that is allocated has a reference or retain count. If a piece of code requires that the object be available, it increases its retain count. When it is done and no longer needs the object, it decrements the retain count. When an object’s retain count reaches 0, it can be deallocated and the memory is returned to the system. Manual reference counting can be difficult to understand if you are not used to thinking about the life cycle of objects in use. Because languages like Java and C# use garbage collection, it can be even more difficult for developers who have used those languages for an extended time to make the transition to Objective-C. Apple recognized this and made significant improvements to the Objective-C compiler that will be discussed later in this section. Though these improvements make manual reference counting much easier, it’s still important for developers to understand exactly how retain counts work and the rules around them.

c02.indd 22

1/25/2014 4:52:42 PM


Explaining the Basics 

❘  23

The first thing to understand is how retain counts work and how they can lead to memory leaks and zombie objects. Listing 2-17 shows one way a memory leak can occur using the SimpleClass described previously in this chapter. Listing 2-17  Memory Leak Example in Objective-C

- (void)simpleMethod { SimpleClass *simpleClassInstance = [[SimpleClass alloc] init]; simpleClassInstance->firstInt = 5; simpleClassInstance->secondInt = 5; [simpleClassInstance sum]; }

A Java or C# developer would not see anything wrong with this code. To them there is a method that creates an instance of the SimpleClass. When the method is done executing, the simpleClassInstance no longer has a reference to it and is eventually deallocated by the garbage collector. This is not the case in Objective-C. When the simpleClassInstance is instantiated using alloc, it has a retain count of one. When the method is done executing, its pointer goes out of scope but keeps a retain count of one. Because the retain count stays above zero, the object is never deallocated. With no pointer still referencing the object, there is no way to decrement its retain count so that it can be deallocated. This is a classic memory leak illustrated in Figure 2-3.

0x000F

0x000E

0x000D

0x000C

0x000B

0x000A

0x0009

0x0008

0x0007

0x0006

0x0005

0x0004

0x0003

0x0002

SimpleClass Object

simpleClassInstance

0x0001

0x0008

Pointer is gone but object is still in memory

Figure 2-3

c02.indd 23

1/25/2014 4:52:42 PM


24 

❘  CHAPTER 2  Introduction to Objective-C

To fix this in Objective-C, you need to explicitly decrement the retain count before leaving the method. You do this by calling the release method of the NSObject class, as shown in Listing 2-18. Release decrements the count by one, which in this example sets the count to zero, which in turn means the object can be deallocated. Listing 2-18:  Using Release in Objective-C

- (void)simpleMethod { SimpleClass *simpleClassInstance = [[SimpleClass alloc] init]; simpleClassInstance->firstInt = 5; simpleClassInstance->secondInt = 5; [simpleClass sum]; [simpleClass release]; }

Another way to fix this is to use the autorelease pool. Instead of explicitly releasing the object when you are done with it, you can call autorelease on it. This puts the object into the autorelease pool, that keeps track of objects within a particular scope of the program. When the program has exited that scope, all the objects in the autorelease pool are released. This is referred to as draining the pool. Listing 2-19 shows how you would implement this. Listing 2-19:  Using Autorelease in Objective-C

- (void)simpleMethod { SimpleClass *simpleClassInstance = [[SimpleClass alloc] init]; [simpleClassInstance autorelease]; simpleClassInstance->firstInt = 5; simpleClassInstance->secondInt = 5; [simpleClass sum]; }

Using alloc generally means that the code creating the object is its owner, which is why it gets a retain count of one. There are other times in your code where an object was created elsewhere but the code using needs to take ownership. The most common example of this is using factory methods to create the object. Factory methods of Objective-C core classes always return an object that has autorelease called on it before it is returned. Listing 2-20 shows how the SimpleClass would generally be implemented now that you understand the autorelease method. Listing 2-20:  Defining a Factory Method Using Autorelease

+ (id)simpleClassWithFirstInt:(int)firstIntValue secondInt:(int)secondIntValue {

c02.indd 24

1/25/2014 4:52:43 PM


Explaining the Basics 

❘  25

SimpleClass *simpleClass = [[SimpleClass alloc] init]; simpleClass.firstInt = firstIntValue; simpleClass.secondInt = secondIntValue; [simpleClass autorelease]; return simpleClass; }

In a piece of code that creates a simpleClass using the factory method, it may want that object to stay in memory even after the autorelease pool has been drained. To increase its retain count and make sure it stays in memory, you would call retain on the instance. Its very important to always call release sometime later in your code if you explicitly retain an object, or else it will cause a memory leak. Listing 2-21 shows a simple example of this; though in a real program, you would probably call release in some other place. Listing 2-21:  Explicitly Retaining an Object

- (void)simpleMethod { SimpleClass *simpleClass = [SimpleClass simpleClassWithFirstInt:1 secondInt:5]; [simpleClass retain]; // do things with the simple class knowing it will not be deallocated [simpleClass release]; }

The other memory management issue you can run into is referencing an object that has already been deallocated. This is called a zombie object. Figure 2-4 illustrates this.

0x000F

0x000E

0x000D

0x000C

0x000B

0x000A

0x0009

0x0008

0x0007

0x0006

0x0005

0x0004

0x0003

0x0002

simpleClassInstance

0x0001

0x0008

Points to deallocated memory

Figure 2-4

c02.indd 25

1/25/2014 4:52:43 PM


26 

❘  CHAPTER 2  Introduction to Objective-C

If this happens during runtime, the execution of your app can become unpredictable or just simply crash. It depends on if the memory address is still part of the memory allocated to your program or if it has been overwritten with a new object. Its conceivable that the memory is still there and your code would execute just fine even though the memory has been marked for reuse. Listing 2-22 demonstrates how a zombie object could occur. Listing 2-22:  Dangling Pointer Example in Objective-C

- (void)simpleMethod { SimpleClass *simpleClassInstance = [[SimpleClass alloc] init]; [simpleClassInstance release]; simpleClass.firstInt = 5; simpleClass.secondInt = 5; int sum = [simpleClass sum]; }

warning  The NSObject class has a property called retainCount. You should never trust this value nor should you ever use it. It may be tempting to look at this value to try and determine when an object will be released or to find a memory leak. You should instead use the debugging instruments included in Xcode, in this case the Leaks instrument. You can learn more about the Leaks instrument at https://developer.apple.com/library/ios/documentation/ AnalysisTools/Reference/Instruments_User_Reference/LeaksInstrument/ LeaksInstrument.html.

Introducing Automatic Reference Counting Manual reference counting differs from garbage collection by setting when objects are allocated and deallocated at compile time instead of runtime. The compiler that Apple uses in its development tools is part of the LLVM Project (llvm.org) and is called Clang (clang.llvm.org). Developers using manual memory management can follow a strict set of rules to ensure that memory is neither leaked nor deallocated prematurely. The developers working on the Clang compiler recognized this and set out to build a tool that could analyze a code base and find where objects could potentially be leaked or be used after they have been released. The tool they released is called the Clang Static Analyzer (clang-analyzer.llvm.org). The Clang Static Analyzer is both a standalone tool as well as integrated in Apple’s Xcode development environment. As an example of how it works, Figure 2-5 shows the results of running the static analyzer on the first example of a memory leak.

c02.indd 26

1/25/2014 4:52:43 PM


Explaining the Basics 

❘  27

Figure 2-5

After building the static analyzer, the compiler developers realized that by detecting rule violations in manual reference counting they could insert the required retain and release calls at compile time. They implemented this in a compiler feature called Automatic Reference Counting (ARC). Because Xcode uses the Clang compiler, iOS developers and Mac developers could use this new feature by simply enabling it in the compiler settings and then removing all their explicit calls to retain, release, and autorelease. Using ARC is becoming standard practice for Mac and iOS developers. This book uses ARC in all sample code. By using ARC you as a new developer do not need to worry about most of the details of memory management, though there are cases in which you do need to know how an object will be treated in memory.

Adding Properties to a Class The SimpleClass example in this chapter has been using public instance variables for its two integer values. In all three languages this is considered bad practice. Declaring instance variables as public leaves your class vulnerable to bad data. There is no way to validate the value being assigned. Instead for all three it is common practice to keep the instance variables private and then implement getter and setter methods. By doing this you can validate the value in the setter method before actually setting the value of the instance variable. Though the concept is the same, the implementation and syntax is different. Listing 2-23 demonstrates how the class should be defined in Java. It’s the most straightforward implementation. The instance variable is declared as private, and two additional methods are added to the class to get and set their values.

c02.indd 27

1/25/2014 4:52:44 PM


28 

❘  CHAPTER 2  Introduction to Objective-C

Listing 2-23:  Defining Getters and Setters in Java

package SamplePackage; public class SimpleClass { private int firstInt; private int secondInt; public void setFirstInt(int firstIntValue) { firstInt = firstIntValue; } public int getFirstInt() { return firstInt; } public void setSecondInt(int secondIntValue) { secondInt = secondIntValue; } public int getSecondInt() { return secondInt; } // other methods discussed previously } // sample code of how to use these methods SimpleClass simpleClassInstance = new SimpleClass(); simpleClassInstance.setFirstInt(1); simpleClassInstance.setSecondInt(2); int firstIntValue = simpleClassInstance.getFirstInt();

In C# this type of implementation is done using properties. A property can be referred to as if it were an instance variable but still uses getters and setters. Listing 2-24 demonstrates this in C#. Listing 2-24:  Properties in C#

namespace SampleNameSpace { public class SimpleClass { private int firstInt; private int secondInt; public int FirstInt { get { return firstInt; } set { firstInt = value; } } public int SecondInt

c02.indd 28

1/25/2014 4:52:44 PM


Explaining the Basics 

❘  29

{ get { return secondInt; } set { secondInt = value; } } // other methods discussed earlier } } // sample code of how to use these properties SimpleClass simpleClassInstance = new SimpleClass(); simpleClassInstance.FirstInt = 1; simpleClassInstance.SecondInt = 2; int firstIntValue = simpleClassInstance.FirstInt

The Objective-C implementation is a bit of a mix of the Java and C# implementations. Like C# it has the idea of properties, but like Java the implementation of the getters and setters are actual methods in the implementation. Listing 2-25 shows how properties are declared in the interface, how they are implemented in the implementation, and a sample of how they are used. Listing 2-25:  Properties in Objective-C

// in the SimpleClass.h file @interface SimpleClass : NSObject { int _firstInt; int _secondInt; } @property int firstInt; @property int secondInt; // other methods discussed earlier @end // in the SimpleClass.m file @implementation SimpleClass - (void)setFirstInt:(int)firstInt { _firstInt = firstInt; } - (int)firstInt { return _firstInt; } - (void)setSecondInt:(int)secondInt

continues

c02.indd 29

1/25/2014 4:52:44 PM


30 

❘  CHAPTER 2  Introduction to Objective-C

Listing 2-25  (continued)

{ _secondInt = secondInt; } - (int)secondInt { return _secondInt; } @end // sample code to create a new instance SimpleClass *simpleClassInstance = [[SimpleClass alloc] init]; [simpleClassInstance setFirstInt:1]; [simpleClassInstance setSecondInt:2]; int firstIntValue = [simpleClassInstance firstInt];

Because properties in Objective-C are the preferred way of exposing data members as public, they have been made easier to use as Objective-C has evolved. The @synthesize keyword was one of those enhancements. By using it, the getter and setter methods are generated for you at compile time instead of you needing to add them into your implementation. You can still override the getter or setter if you need to. As the language progressed, @synthesize became optional as well as even declaring the private instance variables. Instead they are also generated for you. The instance variables are named the same as the property but with a leading underscore. Listing 2-26 shows what a modern Objective-C class looks like. Listing 2-26:  Properties in Modern Objective-C

// in the SimpleClass.h file @interface SimpleClass : NSObject @property int firstInt; @property int secondInt; - (int)sum; @end // in the SimpleClass.m file @implementation SimpleClass - (int)sum { return _firstInt + _secondInt; } @end

c02.indd 30

1/25/2014 4:52:44 PM


Explaining the Basics 

❘  31

Another enhancement made around properties was the introduction of dot notation. Instead of needing to message the object using brackets, you can simply follow the instance of the class with a “.” and the name of the property, as shown in Listing 2-27. Listing 2-27:  Properties and Dot Notation in Objective-C

SimpleClass *simpleClassInstance = [[SimpleClass alloc] init]; simpleClassInstance.firstInt = 5; simpleClassInstance.secondInt = 5; int firstIntValue = simpleClassInstance.firstInt;

Note  Dot notation was not a popular addition to Objective-C when it was first introduced. Since then it has become the standard way of using properties. This book uses dot notation. Some older code and longtime Objective-C developers may avoid its use altogether. Properties can also be pointers to other objects. These properties need a little more attention in Objective-C. In C# you declare properties to other objects the same as you do properties to primitive data types. In Objective-C you also need to tell the compiler if your object is the owner of the other object as well as how its value should be set and retrieved in a threaded environment. For example, assume there is another class called SecondClass. The SimpleClass interface in Listing 2-28 has two properties for this class. Listing 2-28:  Strong and Weak Properties in Modern Objective-C

// in the SimpleClass.h file @interface SimpleClass : NSObject @property (atomic, strong) SecondClass *aSecondClassInstance; @property (nonatomic, weak) SecondClass *anotherSecondClassInstance; @end

In this example the first property has the atomic attribute, whereas the second is nonatomic. Properties by default are atomic. Atomic properties have synthesized getter and setter methods that guarantee that the value is fully retrieved or fully set when accessed simultaneously by different threads. Nonatomic properties do not have this guarantee. Atomic properties have extra overhead in their implementations to make this guarantee. Though it may sound like this makes them threadsafe, that is not the case. A solid threading model with proper locks also creates the same guarantee, so the use of atomic properties is limited. Most often you declare your properties as nonatomic to avoid the extra overhead.

c02.indd 31

1/25/2014 4:52:44 PM


32 

❘  CHAPTER 2  Introduction to Objective-C

The other attribute, strong and weak, are much more important to understand. As you learned earlier in this chapter, an object that has a retain count of zero will be deallocated. The concept of strong and weak with properties is similar. An object that does not have a strong reference to it will be deallocated. By declaring an object property as strong, it will not be deallocated as long as your object points to it. This implies that your object owns the other object. An object property that is declared weak remains in memory as long as some other object has a strong pointer to it.

Company

Employee

Employee

Figure 2-6

Weak properties are used to avoid strong reference cycles. These occur when two objects have properties that point at each other. If both objects have a strong reference to each other, they will never be deallocated, even if no other objects have a reference to either of them. Figure 2-6 illustrates the issue. The strong references between the objects are represented by the solid line arrows. In this example there are three objects. The first is a Company object that represents some company. Every company has employees. In this example the company has two employees represented by the two Employee objects. Within a company there are bosses and workers. A boss needs a way to send messages to their worker the same as the worker needs a way to send messages to their boss. This means both need to have a reference to each other. If the Company object gets deallocated, its references to both Employee objects go with it. This should result in the Employee objects also being deallocated. But if the references between the boss Employee object and the Company worker Employee object are also strong references, then they will not be deallocated. If the references are weak, as illustrated in Figure 2-7, with dashed lines, then losing the strong reference to each Employee object from the Company object will mean there are no longer any strong references pointing to them so they will be properly dealEmployee Employee located. In this example the Company object is the owner of the Employee objects, so it would uses a strong referFigure 2-7 ence to indicate this ownership.

Explaining Strings Java, C#, and Objective-C all have special classes for strings. Objective-C strings can be a bit confusing when you’re first learning to use them, but comparing their use to Java and C# should help reduce the learning curve. This section is a light overview of strings in Objective-C just to get you started. When you understand the basics and limitations, you can easily learn how to deal with specific situations using the class documentation provided by Apple at https://developer.apple. com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/ Reference/NSString.html.

Listing 2-29 shows how you would declare a basic string in Java, C#, and Objective-C. These examples are, of course, just one way to create a string instance. All three languages have many other methods, but the purpose here is just to show how a string would be commonly created.

c02.indd 32

1/25/2014 4:52:45 PM


Explaining the Basics 

❘  33

Listing 2-29:  Declaring Strings in Java, C#, and Objective-C

// declaring a string in Java String myString = "This is a string in Java"; // declaring a string in C# String myString = "This is a string in C#"; // declaring a string in Objective-C NSString *myString = @"This is a string in Objective-C";

In Java and C#, the class that represents a string is simply called String. In Objective-C it’s called NSString. Because Objective-C is a superset of C, you cannot use only quotes to create an NSString. Quoted strings in C create a C string. By adding the @ symbol before the quoted text, you tell the compiler to treat the text as an NSString and not a C string. The C language does not permit overloading operators, which means that you cannot do it in Objective-C, either. Overloading an operator is a way to use an operator in your code instead of calling a method to do the work. The compiler knows that when it sees that operator it uses the method instead. Take for example the Company and Employee objects discussed in the previous section where there is a Company object that has Employee objects. Say you have two Company objects, each with their own set of employees, and you want to “merge” them into a new Company object with all the Employee objects combined. In a language like C#, you could override the + operator and then write code to do the merge, as shown in Listing 2-30. Listing 2-30:  Overloading the + Operator Pseudo Code

Company firstCompany = new Company(); Company secondCompany = new Company(); // you could write a merge method as part of the Company class // then create a new company using it Company thirdCompany = new Company(); thirdCompany.merge(firstCompany); thirdCompany.merge(secondCompany); // or you could override the + operator and do the same in a single line Company thirdCompany = firstCompany + secondCompany;

You cannot do this in Objective-C. This difference becomes stark when comparing the NSString class to the String classes in Java or C#. In all languages a text string is represented in memory as an array of characters. The classes you use to handle strings in code are more or less convenience classes so that you are not dealing with raw character arrays but instead a single object. The implementation of the classes hides that they are character arrays from you. In languages that allow operator overloading, you can do things like concatenating strings by using the overloaded + operator, as shown in Listing 2-31, or calling a method like concat in Java.

c02.indd 33

1/25/2014 4:52:45 PM


34 

❘  CHAPTER 2  Introduction to Objective-C

Listing 2-31:  Concatenating Strings in Java

// this code is correct in Java String firstString = "This is a"; String secondString = "full sentence"; String combinedString = firstString + " " + secondString; // or you could use concat String combinedString = new String(); combinedString.concat(firstString); combinedString.concat(secondString);

You cannot do either of this in Objective-C using the NSString class. First because you cannot overload the + operator, and the second because an NSString cannot be changed after it’s created. It has no methods like concat. It is an immutable object. To do the same in Objective-C, you would use the NSMutableString class, a subclass of NSString. Listing 2-32 shows how you would use the NSMutableString class to append other strings. Listing 2-32:  Concatenating Strings in Objective-C

// this code is correct in Objective-C NSString *firstString = @"This is a"; NSString *secondString = @"full sentence"; NSMutableString [combinedString [combinedString [combinedString

*combinedString = [[NSMutableString alloc] init]; appendString:firstString]; appendString:@" "]; appendString:secondString];

The idea between mutable and immutable objects is used throughout Objective-C. All data ­structures, which are discussed in the next section, have mutable child classes and immutable parent classes. The reasoning behind this is to guarantee that the object will not change while you are using it. Another difference with strings in Objective-C is string formatting. In Java and C# you can create a string using text and integer values simply by using the + operator, as shown in Listing 2-33. Listing 2-33:  Formatting Strings in Java

int numberOne = 1; int numberTwo = 2; String stringWithNumber = "The first number is " + numberOne + " and the second is " + numberTwo;

This would produce the text string "The first number is 1". In Objective-C you do string f­ ormatting the way it’s done in C using the IEEE printf specification (http://pubs.opengroup .org/onlinepubs/009695399/functions/printf.html). Listing 2-34 shows an example of how to create the same text string in Objective-C. It uses the stringWithFormat: static convenience method that allocates the string for you instead of needing to call alloc.

c02.indd 34

1/25/2014 4:52:45 PM


Explaining the Basics 

❘  35

Listing 2-34:  Formatting Strings in Objective-C

int numberOne = 1; NSString *stringWithNumber = [NSString stringWithFormat: @"The first number is %d and the second is %d", numberOne, numberTwo];

The stringWithFormat: method looks for format specifiers in the actual text and then matches them with the list of values that follows. You get a compile error if the formatter does not match the value at the same index in the value list. For a full list of format specifiers, refer to Apples documentation found at https://developer.apple.com/library/ios/documentation/cocoa/conceptual/Strings/Articles/formatSpecifiers.html. One last thing to be mindful of when using strings in Objective-C is string comparison. The difference again goes back to the ability to overload operators. In Java you can compare two strings using the == operator. This ensures that every char at every index is the same between the two strings. In Objective-C you need to remember that the NSString instance variable holds only a pointer to the object in memory. So using the == between two NSString instances will look to see if both are pointing to the same place in memory. Instead you would use the isEqualToString: method, as shown in Listing 2-35. Listing 2-35:  Comparing Strings in Objective-C

NSString *firstString = @"text"; NSString *secondString = @"text"; if(firstString == secondString) { NSLog(@"this will never be true"); } else if ([firstString isEqualToString:secondString]) { NSLog(@"this will be true in this example"); }

tip  The code in Listing 2-35 uses the NSLog() function. This is how you write debugging information to the console in Xcode. It also uses format specifiers followed by a list of values the same as stringWithFormat:. It’s comparable to System.out.println() in Java or Console.WriteLine() in C#.

Using Basic Data Structures Data structures in programming languages are ways to organize data. An object is a data structure, though you may not think of it that way. You are more likely to think of data structures like arrays, sets, or dictionaries. All languages support these types of data structures in one way or another. They typically play a major role in how software is written in various languages. Because of this it’s important to understand them and how they are used. There are a handful of data structures available in Objective-C. This section covers only the ones you use while building the Bands app.

c02.indd 35

1/25/2014 4:52:45 PM


36 

❘  CHAPTER 2  Introduction to Objective-C

The most basic data structure is an array. The simple definition of an array is a list of items stored in a particular order and referenced by their index number. Arrays can be either zero-based, with the first item being at index number 0, or 1-based. C based languages use zero-based arrays, whereas languages such as Pascal use 1-based. Listing 2-36 shows how you would create an array of integers in a C-based language and set the values at each index. Listing 2-36:  Creating an Array of Integers

int integerArray[5]; integerArray[0] = 101; integerArray[1] = 102; integerArray[2] = 103; integerArray[3] = 104; integerArray[4] = 105;

In Java or C# you can also create arrays of objects using a similar syntax. This is not possible in Objective-C. Instead you use the NSArray class and its subclass NSMutableArray. NSArray is like NSString. It is immutable and its objects cannot be changed after it’s created nor can you add or remove objects. This follows the same immutable reasoning as with NSStrings in which your code is ensured that the objects in an NSArray will not change. For arrays that need to change or be dynamic, you need to use the NSMutableArray class. NSArray is a little different from your typical array in Java or C#. In those languages you always declare what type each object is in the array. You don’t do this with NSArray. Instead it will hold any object whose root class is NSObject. Listing 2-37 shows the different ways you can create an NSArray instance in Objective-C. The syntax is a bit different with each, but they all create the same thing. Also keep in mind that you can create an NSString using @"my string" syntax and that NSString is a descendant of NSObject.

Listing 2-37:  Creating NSArrays

NSArray NSArray NSArray NSArray

*arrayOne = [[NSArray alloc] initWithObjects:@"one", @"two", nil]; *arrayTwo = [NSArray arrayWithObjects:@"one", @"two", nil]; *arrayThree = [NSArray arrayWithObject:@"one"]; *arrayFour = @[@"one", @"two", @"three"];

NSString *firstItem = [arrayOne objectAtIndex:0];

The first array is created using the alloc/init pattern. The second creates the same array using the arrayWithObjects: convenience method. Both of these take a C array of objects that is basically just a list of objects followed by a nil. The third is also a convenience method but takes only one object. The last uses NSArray literal syntax, which does not need a nil at the end.

c02.indd 36

1/25/2014 4:52:46 PM


Explaining the Basics 

❘  37

Getting an object from an NSArray is slightly different from arrays in other languages. In Listing 2-38 the items were referenced by their index number by following the name of the array with brackets and the index number. Because brackets are used in Objective-C to send messages to an object, you cannot use this approach. Instead you use the objectAtIndex: method. You can also search for objects in an NSArray using indexOfObject:, or sort them using the sortedArrayUsingSelector:. You learn how to use these later in this book. As mentioned before, the NSArray class is immutable, so you cannot change the values or the size of the array after it has been created. Instead you use an NSMutableArray. Table 2-2 lists the additional methods in the NSMutableArray class that you use to modify the array. Table 2-2:  NSMutableArray Methods Method

Description

addObject:

Adds an object to the end of the array

insertObject:atIndex:

Inserts an object into the array at a specific index

replaceObjectAtIndex:withObject:

Replaces the object at a specific index with the object passed in

removeObjectAtIndex:

Removes an object at the specific index

removeLastObject

Removes the last object in the array

Note  Literal syntax as described in Listing 2-37 can be used only to create an NSArray. You cannot use literal syntax to create an NSMutableArray. Furthermore this book does not use literal syntax in any of the sample code; instead it uses the methods. This is for readability. When working with the sample code feel free to use the literal syntax if you wish.

Similar to the NSArray data structure are the NSSet and NSMutableSet classes. This type of data structure holds a group of objects but not in any particular order. A set is used when you don’t need to access individual objects but instead need to interact with the set as a whole. There are no methods in the NSSet class that return an individual object in the set; however, there are ways to get a subset of a greater set. Sets are particularly useful if you need to check only if an object is included in it. You will not use sets while building the Bands app, so there is no need to go into further detail on them in this chapter.

c02.indd 37

1/25/2014 4:52:46 PM


38 

❘  CHAPTER 2  Introduction to Objective-C

The last common data structure in Objective-C is a dictionary or hash table. It uses a key/value storage paradigm. The NSDictionary and NSMutableDictionary classes represent this type of data structure in Objective-C. An NSDictionary has a set of keys that are an instance of an NSObject descendant. Often you will use an NSString as the key. The value in a dictionary is also a descendant of NSObject. As a way to illustrate how you could use a dictionary in code, think of the company example used previously in this chapter. A company has many employees. Because employees may have the same first and last name, each employee is assigned a unique ID. When employees get a new title, their information needs to be updated, but the only information you have for employees is their ID. If you were to use only arrays or sets to keep track of employees, you would need to iterate through all employees, checking their IDs until you found the correct employee. With a dictionary you could simply look up employees using their unique IDs. Listing 2-38 demonstrates how this would be done in Objective-C using an NSMutableDictionary. Listing 2-38:  Using NSMutableDictionary

NSString *employeeOneID = @"E1"; NSString *employeeTwoID = @"E2"; NSString *employeeThreeID = @"E3"; Employee *employeeOne = [Employee employeeWithUniqueID:employeeOneID]; Employee *employeeTwo = [Employee employeeWithUniqueID:employeeTwoID]; Employee *employeeThree = [Employee employeeWithUniqueID:employeeThreeID]; NSMutableDictionary [employeeDictionary [employeeDictionary [employeeDictionary

*employeeDictionary = [NSMutableDictionary dictionary]; setObject:employeeOne forKey:employeeOneID]; setObject:employeeTwo forKey:employeeTwoID]; setObject:employeeThree forKey:employeeThreeID];

Employee *promotedEmployee = [employeeDictionary objectForKey:@"E2"]; promotedEmployee.title = @"New Title";

In this example there are three Employee objects each with a unique ID. The NSMutableDictionary is created using the convenience method dictionary. The Employee objects are added to the dictionary using the setObject:forKey: method. To get the Employee object whose unique ID is "E2", the code can get it quickly using the objectForKey: method. tip  Because both NSArray and NSDictionary store NSObject instances, you cannot set primitive types such as integers or booleans as values. The NSNumber class can be used instead. It is a descendant of NSObject, so it can be used with both NSArray and NSDictionary and can hold any primitive data type.

c02.indd 38

1/25/2014 4:52:46 PM


Discussing Advanced Concepts 

❘  39

Discussing Advanced Concepts Objective-C is similar in syntax to other C-variant programming languages. Some of the concepts and patterns, though, are different. The rest of this chapter discusses these concepts and patterns so that you can see how they are used in practice while building the Bands app.

Explaining the Model-View-Controller Design Pattern The Model-View-Controller design pattern is another influence of Smalltalk. It’s a high-level design pattern that can be applied to almost any programming language. In Mac and iOS programming, it’s the predominant pattern and is ingrained deeply in Cocoa and Cocoa Touch. To begin developing iOS applications, you need to have a good understanding of how it works so that the classes and user interface design of iOS apps makes sense. The idea is to separate all components of a piece of software into one of three roles. This separation helps to make the components independent of one another as well as configurable and reusable. If done correctly it can greatly reduce the amount of code that needs to be written as well as make the overall architecture of the software easy to understand. This helps new developers coming to a project get up to speed quickly.

The Model The first role is the Model. It is the knowledge or data of the application as well as the rules that define how pieces of data interact with each other. It is responsible for loading and saving data from persistent storage as well as validating that the data is valid. The Model role does not care nor does it store any information about how its data is to be displayed.

The View The second role is the View. It is the visual representation of the model. It does not act on the model in any way nor does it save data to the model. It is strictly the user interface of the software.

The Controller The last role is the Controller. It is the link between the model and the view. When the model changes, it gets notified and knows if there is a view that needs to update its visual display. If a view is interacted with by the user, it notifies the controller about the interaction. The controller then decides if it needs to update the model. To get a better understanding of this, think of a software that might be used by the Company example. The software will be used by administrative assistants to keep track of employees and update their information. Figure 2-8 illustrates how the Model-View-Controller pattern could be used to build this software. The model in this example would be the Employee on the left side of the figure and its underlying database. The employee has three properties: the employee’s name, the employee’s title, and a unique ID for the employee within the database. It is responsible only for loading the employee information from the database and keeping its values in memory.

c02.indd 39

1/25/2014 4:52:46 PM


40 

❘  CHAPTER 2  Introduction to Objective-C

Model

Controller

View

Employee Name Employee Name Employee Name Employee Name Employee Name

Employee - First Name - Last Name - Title

Code

Name:

Title:

Save

Figure 2-8

The views in this example are the list of employees and the employee detail view on the right of the figure. The list of employees shows the name of each employee. The administrative assistant can use this view to select an employee. The employee detail view again shows the name and title of the employee but gives the administrative assistant the ability to change the values displayed. It also has a Save button the administrative assistant can click when he is done updating the information. The controller is the circle that connects the Employee model to the employee list screen and the employee details screen. When the employee list screen needs to be displayed to the administrative assistant, the employee list asks the controller for names of all the employees. It doesn’t care about the employee’s title or unique ID, because it does not display those. It acts as a filter of the model data, so the administrative assistant sees only the information he needs to select the correct employee. When the administrative assistant selects an employee, that interaction is passed again to the controller. The controller then changes the screen to the employee details screen. When this screen is loaded, it asks the controller for the employee’s name and title. The controller retrieves this information from the model and passes it back to the detail view for display. The administrative assistant then changes the title of the employee in the detail view. At this point the change is only a visual change in the employee detail view. It has not changed the value in the model, nor has the database been updated. When the Save button is clicked, the view informs the

c02.indd 40

1/25/2014 4:52:47 PM


Discussing Advanced Concepts 

❘  41

controller about the user interaction. The controller then looks at the data in the view and determines that the model needs to be updated. It passes the new value to the model and tells it to save it to the database. The controller can also update either of the views if another administrative assistant has made a change. Say for instance there are two administrative assistants looking at the same employee detail view. The first changes the name of the employee from “Tom” to “Ted” and then clicks the Save button, which tells the controller to update the model. Because the model changed it notifies the controller that its values have been updated. The controller gets this notification and determines that the value being displayed to the second administrative assistant is out of date, so it tells that detail view to update the visual display of the value. This example illustrates the usefulness of this design pattern. The employee model is independent from the rest of the software yet very reusable. The same can be said with the views. They don’t care what employee model object they are displaying, because they can display any of them. The controller acts as the facilitator, keeping the views and the model in line with each other. In a bigger piece of software, you could have different individuals or even different teams working on the code for each of the layers without needing to know the specifics in the code of other teams.

Learning About Protocols and Delegates Model-View-Controller is a great high-level programming pattern, but to use it in a programming language, you need the tools to make it work. Objective-C has these tools. The model layer is implemented using classes and properties to create reusable objects. The view layer is implemented in the Cocoa and Cocoa Touch APIs, including reusable views and subviews such as buttons and text fields. The controller layer is done by using delegates and data sources to facilitate the communication. Delegates and data sources are used heavily in Objective-C. It’s a way of having one part of the software ask for work to be done by another part. This fits the MVC design pattern with the communication between views and controllers. Because views interact only with controllers and never with the model, they need a way of asking for model data from the controller. This is the role of the data source. When a user interacts with a view, the view needs to tell the controller about it. Delegates are used for this role. Typically, your controller will perform both of these roles. A view needs to define all the questions it may ask its data source and what type of answer it expects in return. It also needs to define all the tasks it may ask the delegate to perform in response to user interaction. In Objective-C this is done through protocols. You can think of a protocol as a contract between the view and its data source or delegate. Consider the employee list view in the company example. This is a simplistic example in this chapter to illustrate how a protocol and a delegate are coded. You implement a list similar to this in Chapter 5, “Using Table Views,” when you learn about table views. In this example the employee list is called the EmployeeListView. For the EmployeeListView to show all the employees in the company, it needs to ask its data source for them. When the administrative assistant selects an employee’s details to view, the EmployeeListView needs to tell its delegate which employee was selected. This calls for two different protocols to be defined: one for the data source and one for the delegate. These protocols would be declared in an EmployeeListView.h file. For the EmployeeListView to ask its data source for employees or tell its delegate that an

c02.indd 41

1/25/2014 4:52:47 PM


42 

❘  CHAPTER 2  Introduction to Objective-C

employee was selected, the view needs a reference to both the delegate and the data source. The references are added as properties with a type of ID, because the view doesn’t care what type of class it is, just as long as it implements the protocols. Listing 2-39 shows how all this would be coded. Listing 2-39:  Employee List Data Source and Delegate Protocol Declaration

@protocol EmployeeListViewDataSource - (NSArray *)getAllEmployees; @end @protocol EmployeeListViewDelegate - (void)didSelectEmployee:(Employee *)selectedEmployee; @end @interface EmployeeListView : NSObject @property (nonatomic, weak) id dataSource; @property (nonatomic, weak) id delegate; @end

The controller in the example is called the EmployeeListViewController. In order for the Employee ListViewController to communicate with the EmployeeListView, the EmployeeListView Controller needs to declare that it implements the EmployeeListViewDataSource and Employee ListViewDelegate protocols. Controllers often have a reference to the view they are controlling in a property as well. In this example, the reference to the EmployeeListView is set through the initWith EmployeeListView: method. Listing 2-40 shows how to do this in code. Listing 2-40:  Employee List Data Source Protocol Declaration

#import "EmployeeListView.h" @interface EmployeeListViewController : NSObject <EmployeeListViewDataSource, EmployeeListViewDelegate> - (id)initWithEmployeeListView:(EmployeeListView *)employeeListView; @property (nonatomic, weak) EmployeeListView *employeeListView; @end

Note  In both the interface for the EmployeeListView and EmployeeList ViewController, all the properties have the weak attribute. This is to prevent the Strong Retain Cycle issue explained earlier in this chapter.

c02.indd 42

1/25/2014 4:52:47 PM


Discussing Advanced Concepts 

❘  43

In the implementation of the EmployeeListViewController, you need to add the actual implementation of the methods listed in the protocols it declares. You also need to set it as both the data source and the delegate of the EmployeeListView. There are a few ways to do this in Xcode, but as a simple example, it is done in the initWithEmployeeListView: method. Listing 2-41 shows what the EmployeeListViewController.m file would look like. Listing 2-41:  Employee Controller Implementation

#import "EmployeeListViewController.h" @implementation EmployeeListViewController - (id)initWithEmployeeListView:(EmployeeListView *)employeeListView { self.employeeListView = employeeListView; self.employeeListView.dataSource = self; self.employeeListView.delegate = self; } - (NSArray *)getAllEmployees; { // ask the model for all the employees // create an NSArray of all the employees // return the array return allEmployeesArray; } - (void)didSelectEmployee:(Employee *)selectedEmployee; { // display the employee detail view with the selected employee } @end

Now when the EmployeeListView needs to get the employees it needs to show or when an employee is selected, it can simply call the methods of the protocols using its references, as shown in Listing 2-42. Listing 2-42:  Calling Methods of Delegates and Data Sources

// in the implementation of the EmployeeListView it would // get the array of employees using this code NSArray *allEmployees = [self.dataSource getAllEmployees]; // to tell its delegate that an employee was selected // it would use this code [self.delegate didSelectEmployee:selectedEmployee];

c02.indd 43

1/25/2014 4:52:47 PM


44 

❘  CHAPTER 2  Introduction to Objective-C

Using Blocks Blocks are a relatively new programming construct first introduced to iOS programming with the release of iOS 4.0. The concept behind them has been in other languages for a longer time. C and C++ have function pointers, C# has lambda expressions, and JavaScript has callbacks. If you have used any of these, the idea of blocks should be relatively easy to grasp. If you have not, you may want to research them to get a better understanding, though you don’t need to. This section gives a quick overview of the syntax and a high-level explanation that should be enough for you to understand how to use them when needed while building the Bands app. A block in its most simple definition is a chunk of code that can be assigned to a variable or used as a parameter to another method. The ^ operator is used to declare a block while the actual code is contained in between curly brackets. Blocks can have their own list of parameters as well as their own return type. Blocks in Objective-C have the special capability to use local variables declared within the scope they are defined. In this book you use blocks in the context of completion handlers to other methods. When you call these methods, you pass them whatever parameters they need and then also declare a block of code that gets invoked at some point within the method. For example, imagine a method that retrieves a string from a URL. This example uses a fake object called networkFetcher that has a fake method called str ingFromUrl:withCompletionHandler:, so you can get a feel for the syntax of blocks. You do this using real Cocoa frameworks in Chapter 10, “Getting Started with Web Services,” but, as stated earlier, this is just a quick overview of the block syntax. Listing 2-43 shows the code for this simple example. Listing 2-43:  Defining an Inline Block in Objective-C

NSString *websiteUrl = @"http://www.simplesite.com/string"; [networkFetcher stringFromUrl:websiteUrl withCompletionHandler:^(NSString* theString) { NSLog("The string: %@ was fetched from %@, theString, websiteUrl); }];

This code example defines an inline block that is passed as a parameter to the stringFromUrl:withCompletionHandler: method. The ^ character signifies the start of the block. The (NSString* theString) portion is the parameter list being passed into the block. The code of the block is contained in the {} that follows. The code simply prints the string that was retrieved along with the URL string. What happens when this is executed is the networkFetcher class makes the network connection and does all the hard work of actually getting the string. When it’s done, it calls the block of code with that string. This example shows how you will use blocks in this book but barely scrapes the surface of them. They are a powerful tool that can change how software is designed and implemented.

Handling Errors One last concept that needs to be discussed is error handling in Objective-C. This is particularly important to developers coming from a Java background. Objective-C does have exceptions and

c02.indd 44

1/25/2014 4:52:47 PM


Discussing Advanced Concepts 

❘  45

try/catch/finally statements; although they are rarely used. You may have the urge to continue using them as you learn Objective-C but you shouldn’t. It is not common practice.

An exception in most object-oriented programming (OOP) languages is a special object that gets created when an error has occurred. This object is then “thrown” to the system runtime. The runtime, in turn, looks for code that “catches” the exception and handles the error in some manner. If nothing catches the exception, it is considered an uncaught exception and generally will crash the program that is running. In Java and C#, exceptions are a normal part of the coding process and execution. A common use is when you want to do something but you’re not sure if you will have everything you need to accomplish it at runtime, such as reading from a file. If the file doesn’t exist, that’s an error and the user should be notified. In Java or C# you would use a try/catch/finally statement to detect this situation. Listing 2-44 shows some pseudo code of what this might look like in either of those languages without going into the implementation details. Listing 2-44:  Catching Exceptions

public void readFile(string fileName) { // create the things you would need to read the file FileReaderClass fileReader = new FileReaderClass(fileName); try { FileReaderClass.ReadFile(); } catch(Exception ex) { // uh-oh, something happened. Alert the user! } finally { // clean up anything that needs to be cleaned up } }

In Objective-C this type of coding is very rarely used. Instead it’s preferred to use the NSError class. Reading a file into a string in Objective-C takes this approach, as shown in Listing 2-45. Listing 2-45:  Using NSError in Objective-C

- (void) readFile:(NSString *)fileName { NSError *error = nil; NSString *fileContents = [NSString stringWithContentsOfFile:fileName encoding:NSASCIIStringEncoding error:&error]; if(error != nil)

continues

c02.indd 45

1/25/2014 4:52:48 PM


46 

❘  CHAPTER 2  Introduction to Objective-C

Listing 2-45  (continued)

{ // uh-oh, something happened. Alert the user! } }

In this example the code first creates an NSError pointer with a nil value. It then passes the error instance to the method by reference instead of by value. The idea of passing a parameter by reference or by value is in both C# and Java. For typical method calls the object is passed by value, which means the method gets a copy of the object and not the object itself. If the method modifies the object, it modifies only its own copy of the object and not the original. When the method returns, your object is the same and does not reflect those changes. In this example you use the & (ampersand) symbol to pass the address of the object and not the object itself. If an error occurs while reading the file, the method creates a new NSError object and assigns it to that address. When the method returns you check to see if your error points to an actual error object now or if it still points to nil. You know when to pass a parameter by reference when you see ** in the method signature. The full signature in this example is + (instancetype)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error

Though using try/catch is not recommended, it is possible. There are base classes that throw exceptions. Using the NSString class again, you could get an exception if you try to get the character at an index that is out of bounds for the underlying character array. Listing 2-46 shows what this looks like. Listing 2-46:  Catching Exceptions in Objective-C

- (void)someMethod { NSString *myString = @"012"; @try { [myString characterAtIndex:3]; } @catch(NSException *ex) { // do something with the exception } @finally { // do any cleanup } }

The Objective-C way to handle this situation would be to add a check to the code making sure the method will not fail before calling it. Listing 2-47 shows how you would use this approach instead of a try/catch.

c02.indd 46

1/25/2014 4:52:48 PM


Summary 

❘  47

Listing 2-47:  Catching Exceptions in Objective-C

- (void)someMethod { NSString *myString = @"012"; if([myString length] >= 3) { [myString characterAtIndex:3]; } else { // nope, can't make that method call! } }

Summary Objective-C can look strange if you are coming to it from other object-oriented languages such as C# and Java. The syntax is kind of funny, but the basic concepts and programming constructs are all similar. There are fundamental differences; the biggest being memory management. Objective-C and its tools and compilers have come a long way, however, in recent years, making it less of a burden to developers. If you are comfortable with other object-oriented programming languages, the learning curve of Objective-C is smaller than you may think. The more advanced topics covered in this chapter may seem difficult to understand at this point, but as you move through the book, they will become clearer. The easiest way to understand new concepts and patterns is to use them in practice to build something. In the next chapter that is exactly what you do as you begin writing the Bands app.

Exercises

c02.indd 47

1.

What language is the messaging syntax of Objective-C based on?

2.

What are the two files used to define a class in Objective-C and what are their extensions?

3.

What is the base class almost all Objective-C classes are derived from?

4.

Define the Objective-C interface for a class named ChapterExercise with one method named writeAnswer, which takes no arguments and returns nothing.

5.

What code would you write to instantiate the ChapterExercise class?

6.

What are the keywords in Objective-C that increment and decrement the reference count of an object?

7.

What does ARC stand for?

1/25/2014 4:52:48 PM


48 

❘  CHAPTER 2  Introduction to Objective-C

8.

What does the strong attribute mean on a class property?

9.

Why can’t you concatenate two NSString instances using the + operator as you can in Java or C#?

10. How do you compare the value of two NSString instances? 11. What is the difference between the NSArray and NSMutableArray classes? 12. What does MVC stand for? 13. How would you declare that the ChapterExercise class implements a theoretical Chapter ExerciseDelegate protocol? 14. What class is recommended in Objective-C in place of using NSException?

c02.indd 48

1/25/2014 4:52:48 PM


Summary 

❘  49

➤ What You Learned in This Chapter

c02.indd 49

Topic

Key Concepts

Objective-C

The language used to develop both Mac and iOS applications is Objective-C. First developed in the early 1980s, it has evolved into an incredibly powered object-oriented programming language with many similarities to Java and C#.

Classes and Objects

The basic building block of all object-oriented programming languages are objects and the classes that define them.

Manual Reference Counting

There are two mainstream approaches to memory management. Languages like Java and C# use Garbage Collection, whereas Objective-C uses Manual Reference Counting, where the developer is responsible for the life cycle of objects in use.

Automatic Reference Counting

A modern approach to manual reference counting takes the responsibility of keeping track of reference counts out of the hands of developers and passes it instead to the compiler.

Class Properties

Object-oriented programming languages recommend using public getter and setter methods to change member values while keeping the actual member variables private. Objective-C implements this concept using class properties.

Data Structures

Higher-level programming languages are designed with built-in data structures such as arrays and dictionaries that developers use to organize data to make their code fast and efficient. Objective-C includes the basic data structures NSArray, NSSet, and NSDictionary.

The Model-ViewController Design Pattern

The Model-View-Controller design pattern is a high-level design pattern that separates all the components in a piece of software into three roles. These roles help to promote independence and reusability.

Delegates and Protocols

The Cocoa framework uses the concept of delegates and protocols to facilitate the Model-View-Controller design pattern by formalizing how components in different roles communicate and pass data to each other.

Objective-C Error Handling

All object-oriented programming languages include exceptions and errors. The way they are used, however, can vary widely. Understanding how Objective-C and Cocoa approach them is fundamental to writing iOS applications.

1/25/2014 4:52:48 PM


c02.indd 50

1/25/2014 4:52:48 PM


JAVASCRIPT &JQUERY interactive front-end web development

JON DUCKETT


TABLE OF CONTENTS

Introduction Chapter 1: The ABC of Programming Chapter 2: Basic JavaScript Instructions Chapter 3: Functions, Methods & Objects Chapter 4: Decisions & Loops Chapter 5: Document Object Model Chapter 6: Events Chapter 7: jQuery Chapter 8: Ajax & JSON Chapter 9: APIs Chapter 10: Error Handling & Debugging Chapter 11: Content Panels Chapter 12: Filtering, Searching & Sorting Chapter 13: Form Enhancement & Validation Index

CODE DOWNLOAD

1 11 53 85 145 183 243 293 367 409 449 487 527 567 623

Try out & download the code in this book

www.javascriptbook.com


1

THE ABC OF PROGRAMMING


Before you learn how to read and write the JavaScript language itself, you need to become familiar with some key concepts in computer programming. They will be covered in three sections:

A

B

What is a script and how do I create one?

How do computers fit in with the world around them?

C How do I write a script for a web page?

Once you have learned the basics, the following chapters will show how the JavaScript language can be used to tell browsers what you want them to do.

12

THE ABC OF PROGRAMMING


1/a

WHAT IS A SCRIPT AND HOW DO I CREATE ONE?

THE ABC OF PROGRAMMING

13


A SCRIPT IS A SERIES OF INSTRUCTIONS A script is a series of instructions that a computer can follow to achieve a goal. You could compare scripts to any of the following: RECIPES

HANDBOOKS

MANUALS

By following the instructions in a recipe, one-by-one in the order set out, cooks can create a dish they have never made before.

Large companies often provide handbooks for new employees that contain procedures to follow in certain situations.

Some scripts are simple and only deal with one individual scenario, like a simple recipe for a basic dish. Other scripts can perform many tasks, like a recipe for a complicated three-course meal.

For example, hotel handbooks may contain steps to follow in different scenarios such as when a guest checks in, when a room needs to be tidied, when a fire alarm goes off, and so forth.

Mechanics often refer to car repair manuals when servicing models they are not familiar with. These manuals contain a series of tests to check the key functions of the car are working, along with details of how to fix any issues that arise.

Another similarity is that, if you are new to cooking or programming, there is a lot of new terminology to learn.

In any of these scenarios, the employees need to follow only the steps for that one type of event. (You would not want someone going through every single step in the entire handbook while you were waiting to check in.) Similarly, in a complex script, the browser might use only a subset of the code available at any given time.

For example, there might be details about how to test the brakes. If they pass this test, the mechanic can then go on to the next test without needing to fix the brakes. But, if they fail, the mechanic will need to follow the instructions to repair them. The mechanic can then go back and test the brakes again to see if the problem is fixed. If the brakes now pass the test, the mechanic knows they are fixed and can move onto the next test. Similarly, scripts can allow the browser to check the current situation and only perform a set of steps if that action is appropriate.

14

THE ABC OF PROGRAMMING


Scripts are made up of instructions a computer can follow step-by-step. A browser may use different parts of the script depending on how the user interacts with the web page. Scripts can run different sections of the code in response to the situation around them.

15


WRITING A SCRIPT To write a script, you need to first state your goal and then list the tasks that need to be completed in order to achieve it. Humans can achieve complex goals without thinking about them too much, for example you might be able to drive a car, cook breakfast, or send an email without a set of detailed instructions. But the first time we do these things they can seem daunting. Therefore, when learning a new skill, we often break it down into smaller tasks, and learn one of these at a time. With experience these individual tasks grow familiar and seem simpler. Some of the scripts you will be reading or writing when you have finished this book will be quite complicated and might look intimidating at first. However, a script is just a series of short instructions, each of which is performed in order to solve the problem in hand. This is why creating a script is like writing a recipe or manual that allows a computer to solve a puzzle one step at a time. It is worth noting, however, that a computer doesn't learn how to perform tasks like you or I might; it needs to follow instructions every time it performs the task. So a program must give the computer enough detail to perform the task as if every time were its first time.

16

THE ABC OF PROGRAMMING


Start with the big picture of what you want to achieve, and break that down into smaller steps. 1: DEFINE THE GOAL First, you need to define the task you want to achieve. You can think of this as a puzzle for the computer to solve.

2: DESIGN THE SCRIPT To design a script you split the goal out into a series of tasks that are going to be involved in solving this puzzle. This can be represented using a flowchart. You can then write down individual steps that the computer needs to perform in order to complete each individual task (and any information it needs to perform the task), rather like writing a recipe that it can follow.

3: CODE EACH STEP Each of the steps needs to be written in a programming language that the computer understands. In our case, this is JavaScript. As tempting as it can be to start coding straight away, it pays to spend time designing your script before you start writing it.

THE ABC OF PROGRAMMING

17


DESIGNING A SCRIPT: TASKS Once you know the goal of your script, you can work out the individual tasks needed to achieve it. This high-level view of the tasks can be represented using a flowchart.

FLOWCHART: TASKS OF A HOTEL CLEANER CHECK EACH ROOM

Does room need tidying? Tidy room

Does minibar need restocking? Restock GO TO NEXT ROOM

18

THE ABC OF PROGRAMMING


DESIGNING A SCRIPT: STEPS Each individual task may be broken down into a sequence of steps. When you are ready to code the script, these steps can then be translated into individual lines of code.

LIST: STEPS REQUIRED TO TIDY A ROOM

STEP 1

Remove used bedding

STEP 2

Wipe all surfaces

STEP 3

Vacuum floors

STEP 4

Fit new bedding

STEP 5

Remove used towels and soaps

STEP 6

Clean toilet, bath, sink, surfaces

STEP 7

Place new towels and soaps

STEP 8

Wipe bathroom floor

As you will see on the next page, the steps that a computer needs to follow in order to perform a task are often very different from those that you or I might take.

THE ABC OF PROGRAMMING

19


FROM STEPS TO CODE Every step for every task shown in a flowchart needs to be written in a language the computer can understand and follow. In this book, we are focussing on the JavaScript language and how it is used in web browsers. Just like learning any new language, you need to get to grips with the: ●●

Vocabulary: The words that computers understand

●●

Syntax: How you put those words together to create instructions computers can follow

Along with learning the language itself, if you are new to programming, you will also need to learn how a computer achieves different types of goals using a programmatic approach to problem-solving.

Computers are very logical and obedient. They need to be told every detail of what they are expected to do, and they will do it without question. Because they need different types of instructions compared to you or I, everyone who learns to program makes lots of mistakes at the start. Don't be disheartened; in Chapter 10 you will see several ways to discover what might have gone wrong – programmers call this debugging.

20

THE ABC OF PROGRAMMING


You need to learn to â&#x20AC;&#x153;thinkâ&#x20AC;? like a computer because they solve tasks in different ways than you or I might approach them. Computers solve problems programmatically; they follow series of instructions, one after another. The type of instructions they need are often different to the type of instructions you might give to another human. Therefore, throughout the book you will not only learn the vocabulary and syntax that JavaScript uses, but you will also learn how to write instructions that computers can follow. For example, when you look at the picture on the left how do you tell which person is the tallest? A computer would need explicit, step-by-step instructions, such as: 1. Find the height of the first person 2. Assume he or she is the "tallest person" 3. Look at the height of the remaining people oneby-one and compare their height to the "tallest person" you have found so far 4. At each step, if you find someone whose height is greater than the current "tallest person", he or she becomes the new "tallest person" 5. Once you have checked all the people, tell me which one is the tallest So the computer needs to look at each person in turn, and for each one it performs a test ("Are they taller than the current tallest person?"). Once it has done this for each person it can give its answer.

THE ABC OF PROGRAMMING

21


DEFINING A GOAL & DESIGNING THE SCRIPT Consider how you might approach a different type of script. This example calculates the cost of a name plaque. Customers are charged by the letter. The first thing you should do is detail your goals for the script (what you want it to achieve): Customers can have a name added to a plaque; each letter costs $5. When a user enters a name, show them how much it will cost.

SKS

Next, break it into a series of tasks that have to be performed in order to achieve the goals: 1. The script is triggered when the button is clicked. 2. It collects the name entered into the form field. 3. It checks that the user has entered a value. 4. If the user has not entered anything, a message will appear telling them to enter a name. 5. If a name has been entered, calculate the cost of the sign by multiplying the number of letters by the cost per letter. 6. Show how much the plaque costs. (These numbers correspond with the flowchart on the right-hand page.)

22

THE ABC OF PROGRAMMING


SKETCHING OUT THE TASKS IN A FLOWCHART Often scripts will need to perform different tasks in different situations. You can use flowcharts to work out how the tasks fit together. The flowcharts show the paths between each step.

1

When the button has been clicked

2

Get the name entered into the form

3

Is there a name to get?

4

Ask user the user to enter a name

5

Calculate the cost of the sign (letters x price)

6

Show the cost of the sign on the screen

Arrows show how the script moves from one task to the next. The different shapes represent different types of tasks. In some places there are decisions which cause the code to follow different paths. You will learn how to turn this example into code in Chapter 2. You will also see many more examples of different flowcharts throughout the book, and you will meet code that helps you deal with each of these types of situations. Some experienced programmers use more complex diagram styles that are specifically designed to represent code â&#x20AC;&#x201C; however, they have a steeper learning curve. These informal flowcharts will help you understand how scripts work while you are in the process of learning the language.

FLOWCHART KEY Generic step

Event

Input or output

Decision

THE ABC OF PROGRAMMING

23


SUMMARY THE ABC OF PROGRAMMING

A: What is a script and how do I create one?

24

SS

A script is a series of instructions that the computer can follow in order to achieve a goal.

SS

Each time the script runs, it might only use a subset of all the instructions.

SS

Computers approach tasks in a different way than humans, so your instructions must let the computer solve the task programmatically.

SS

To approach writing a script, break down your goal into a series of tasks and then work out each step needed to complete that task (a flowchart can help).

THE ABC OF PROGRAMMING


1/b

HOW DO COMPUTERS FIT IN WITH THE WORLD AROUND THEM?

THE ABC OF PROGRAMMING

25


COMPUTERS CREATE MODELS OF THE WORLD USING DATA Here is a model of a hotel, along with some model trees, model people, and model cars. To a human, it is clear what kind of real-world object each one represents.

26

THE ABC OF PROGRAMMING


A computer has no predefined concept of what a hotel or car is. It does not know what they are used for. Your laptop or phone will not have a favorite brand of car, nor will it know what star rating your hotel is.

So how do we use computers to create hotel booking apps, or video games where players can race a car? The answer is that programmers create a very different kind of model, especially for computers.

Programmers make these models using data. That is not as strange or as scary as it sounds because the data is all the computer needs in order to follow the instructions you give it to carry out its tasks.

OBJECT TYPE: HOTEL

OBJECT TYPE: CAR

OBJECT TYPE: CAR

THE ABC OF PROGRAMMING

27


OBJECTS & PROPERTIES

If you could not see the picture of the hotel and cars, the data in the information boxes alone would still tell you a lot about this scene.

OBJECTS (THINGS)

PROPERTIES (CHARACTERISTICS)

In computer programming, each physical thing in the world can be represented as an object. There are two different types of objects here: a hotel and a car.

Both of the cars share common characteristics. In fact, all cars have a make, a color, and engine size. You could even determine their current speed. Programmers call these characteristics the properties of an object.

Programmers might say that there is one instance of the hotel object, and two instances of the car object. Each object can have its own: ●●

Properties

●●

Events

●●

Methods

Together they create a working model of that object.

Each property has a name and a value, and each of these name/value pairs tells you something about each individual instance of the object. The most obvious property of this hotel is its name. The value for that property is Quay. You can tell the number of rooms the hotel has by looking at the value next to the rooms property.

The idea of name/value pairs is used in both HTML and CSS. In HTML, an attribute is like a property; different attributes have different names, and each attribute can have a value. Similarly, in CSS you can change the color of a heading by creating a rule that gives the color property a specific value, or you can change the typeface it is written in by giving the font-family property a specific value. Name/value pairs are used a lot in programming.

28

THE ABC OF PROGRAMMING


HOTEL OBJECT

CAR OBJECTS

The hotel object uses property names and values to tell you about this particular hotel, such as the hotel's name, its rating, the number of rooms it has, and how many of these are booked. You can also tell whether or not this hotel has certain facilities.

The car objects both share the same properties, but each one has different values for those properties. They tell you the make of car, what speed each car is currently traveling at, what color it is, and what type of fuel it requires.

OBJECT TYPE: HOTEL PROPERTIES name name

Quay

rating rating

4

rooms rooms

42

bookings bookings

21

gym gym

false

pool pool

true

OBJECT TYPE: CAR PROPERTIES

OBJECT TYPE: CAR PROPERTIES

make make

BMW

make

Porsche

currentSpeed currentSpeed

30mph

currentSpeed

20mph

color color

silver

color

silver

fuel fuel

diesel

fuel

gasoline

THE ABC OF PROGRAMMING

29


EVENTS

In the real world, people interact with objects. These interactions can change the values of the properties in these objects.

WHAT IS AN EVENT?

WHAT DOES AN EVENT DO?

There are common ways in which people interact with each type of object. For example, in a car a driver will typically use at least two pedals. The car has been designed to respond differently when the driver interacts with each of the different pedals:

Programmers choose which events they respond to. When a specific event happens, that event can be used to trigger a specific section of the code.

●●

The accelerator makes the car go faster

●●

The brake slows it down

Similarly, programs are designed to do different things when users interact with the computer in different ways. For example, clicking on a contact link on a web page could bring up a contact form, and entering text into a search box may automatically trigger the search functionality. An event is the computer's way of sticking up its hand to say, "Hey, this just happened!"

30

THE ABC OF PROGRAMMING

Scripts often use different events to trigger different types of functionality. So a script will state which events the programmer wants to respond to, and what part of the script should be run when each of those events occur.


HOTEL OBJECT

CAR OBJECTS

A hotel will regularly have bookings for rooms. Each time a room is reserved, an event called book can be used to trigger code that will increase the value of the bookings property. Likewise, a cancel event can trigger code that decreases the value of the bookings property.

A driver will accelerate and brake throughout any car journey. An accelerate event can trigger code to increase the value of the currentSpeed property and a brake event can trigger code to decrease it. You will learn about the code that responds to the events and changes these properties on the next page.

OBJECT TYPE: HOTEL EVENT

happens when:

book book

reservation is made

cancel cancel

reservation is cancelled

OBJECT TYPE: CAR

OBJECT TYPE: CAR

EVENT

happens when:

EVENT

happens when:

brake brake

driver slows down

brake brake

driver slows down

accelerate accelerate

driver speeds up

accelerate accelerate

driver speeds up

THE ABC OF PROGRAMMING

31


METHODS

Methods represent things people need to do with objects. They can retrieve or update the values of an object's properties.

32

WHAT IS A METHOD?

WHAT DOES A METHOD DO?

Methods typically represent how people (or other things) interact with an object in the real world.

The code for a method can contain lots of instructions that together represent one task.

They are like questions and instructions that:

When you use a method, you do not always need to know how it achieves its task; you just need to know how to ask the question and how to interpret any answers it gives you.

●●

Tell you something about that object (using information stored in its properties)

●●

Change the value of one or more of that object's properties

THE ABC OF PROGRAMMING


HOTEL OBJECT

CAR OBJECTS

Hotels will commonly be asked if any rooms are free. To answer this question, a method can be written that subtracts the number of bookings from the total number of rooms. Methods can also be used to increase and decrease the value of the bookings property when rooms are booked or cancelled.

The value of the currentSpeed property needs to go up and down as the driver accelerates and brakes. The code to increase or decrease the value of the currentSpeed property could be written in a method, and that method could be called changeSpeed().

OBJECT TYPE: HOTEL METHOD

what it does:

makeBooking() makeBooking()

increases value of bookings property

cancelBooking() cancelBooking()

decreases value of bookings property

checkAvailability() checkAvailability()

subtracts value of bookings property from value of rooms property and returns number of rooms available

OBJECT TYPE: CAR

OBJECT TYPE: CAR METHOD

what it does:

METHOD

what it does:

changeSpeed() changeSpeed()

increases or decreases value of currentSpeed property

changeSpeed() changeSpeed()

increases or decreases value of currentSpeed property

THE ABC OF PROGRAMMING

33


PUTTING IT ALL TOGETHER

Computers use data to create models of things in the real world. The events, methods, and properties of an object all relate to each other: Events can trigger methods, and methods can retrieve or update an object's properties.

OBJECT TYPE: HOTEL

1

EVENT

happens when:

method called:

PROPERTIES

book book

reservation is made

makeBooking()

name name

Quay

cancel cancel

reservation is cancelled

cancelBooking()

METHOD

2

34

what it does:

rating rating

4

rooms rooms

42

bookings bookings

22

makeBooking() makeBooking()

increases value of bookings property

gym gym

false

cancelBooking() cancelBooking()

decreases value of bookings property

pool pool

true

checkAvailability() checkAvailability()

subtracts value of bookings property from value of rooms property and returns number of rooms available

THE ABC OF PROGRAMMING

3


HOTEL OBJECT

CAR OBJECTS

1. When a reservation is made, the book event fires. 2. The book event triggers the makeBooking() method, which increases the value of the bookings property. 3. The value of the bookings property is changed to reflect how many rooms the hotel has available.

1. As a driver speeds up, the accelerate event fires. 2. The accelerate event calls the changeSpeed() method, which in turn increases the value of the currentSpeed property. 3. The value of the currentSpeed property reflects how fast the car is traveling.

OBJECT TYPE: CAR

1

2

EVENT

happens when:

method called:

PROPERTIES

brake brake

driver slows down

changeSpeed()

make make

BMW

accelerate accelerate

driver speeds up

changeSpeed()

currentSpeed currentSpeed

45mph

color color

silver

fuel fuel

diesel

METHOD

what it does:

changeSpeed() changeSpeed()

increases or decreases value of currentSpeed property

3

THE ABC OF PROGRAMMING

35


WEB BROWSERS ARE PROGRAMS BUILT USING OBJECTS You have seen how data can be used to create a model of a hotel or a car. Web browsers create similar models of the web page they are showing and of the browser window that the page is being shown in.

36

WINDOW OBJECT

DOCUMENT OBJECT

On the right-hand page you can see a model of a computer with a browser open on the screen.

The current web page loaded into each window is modelled using a document object.

The browser represents each window or tab using a window object. The location property of the window object will tell you the URL of the current page.

The title property of the document object tells you what is between the opening <title> and closing </title> tag for that web page, and the lastModified property of the document object tells you the date this page was last updated.

THE ABC OF PROGRAMMING


OBJECT TYPE: WINDOW PROPERTIES location location

http://www.javascriptbook.com/

OBJECT TYPE: DOCUMENT PROPERTIES URL URL

http://www.javascriptbook.com/

lastModified lastModified

09/04/2014 15:33:37

title title

Learn JavaScript & jQuery A book that teaches you in a nicer way

THE ABC OF PROGRAMMING

37


THE DOCUMENT OBJECT REPRESENTS AN HTML PAGE Using the document object, you can access and change what content users see on the page and respond to how they interact with it.

Like other objects that represent real-world things, the document object has:

Because all major web browsers implement the document object in the same way, the people who create the browsers have already:

PROPERTIES

●●

Properties describe characteristics of the current web page (such as the title of the page).

Implemented properties that you can access to find out about the current page in the browser

●●

Written methods that achieve some common tasks that you are likely to want to do with an HTML page

METHODS Methods perform tasks associated with the document currently loaded in the browser (such as getting information from a specified element or adding new content).

EVENTS You can respond to events, such as a user clicking or tapping on an element.

38

THE ABC OF PROGRAMMING

So you will be learning how to work with this object. In fact, the document object is just one of a set of objects that all major browsers support. When the browser creates a model of a web page, it not only creates a document object, but it also creates a new object for each element on the page. Together these objects are described in the Document Object Model, which you will meet in Chapter 5.


OBJECT TYPE: DOCUMENT PROPERTIES URL URL

http://www.javascriptbook.com/

lastModified lastModified

09/04/2014 15:33:37

title title

Learn JavaScript & jQuery A book that teaches you in a nicer way

EVENT

happens when:

load load

page and assets have finished loading

click click

user clicks the mouse over the page

keypress keypress

user presses down on a key

METHOD

what it does:

write() write()

adds new content to the document

getElementById() getElementById()

accesses an element when you state its id attribute

THE ABC OF PROGRAMMING

39


HOW A BROWSER SEES A WEB PAGE In order to understand how you can change the content of an HTML page using JavaScript, you need to know how a browser interprets the HTML code and applies styling to it. 1: RECEIVE A PAGE AS HTML CODE

2: CREATE A MODEL OF THE PAGE AND STORE IT IN MEMORY

3: USE A RENDERING ENGINE TO SHOW THE PAGE ON SCREEN

Each page on a website can be seen as a separate document. So, the web consists of many sites, each made up of one or more documents.

The model shown on the right hand page is a representation of one very basic page. Its structure is reminiscent of a family tree. At the top of the model is a document object, which represents the whole document.

If there is no CSS, the rendering engine will apply default styles to HTML elements. However, the HTML code for this example links to a CSS style sheet, so the browser requests that file and displays the page accordingly.

Beneath the document object each box is called a node. Each of these nodes is another object. This example features three types of nodes representing elements, text within the elements, and attribute.

When the browser receives CSS rules, the rendering engine processes them and applies each rule to its corresponding elements. This is how the browser positions the elements in the correct place, with the right colors, fonts, and so on.

All major browsers use a JavaScript interpreter to translate your instructions (in JavaScript) into instructions the computer can follow. When you use JavaScript in the browser, there is a part of the browser that is called an interpreter (or scripting engine).

40

THE ABC OF PROGRAMMING

The interpreter takes your instructions (in JavaScript) and translates them into instructions the browser can use to achieve the tasks you want it to perform.

In an interpreted programming language, like JavaScript, each line of code is translated one-by-one as the script is run.


1

<!DOCTYPE html> <html> <head> <title>Constructive &amp; Co.</title> <link rel="stylesheet" href="css/c01.css" /> </head> <body> <h1>Constructive &amp; Co.</h1> <p>For all orders and inquiries please call <em>555-3344</em></p> </body> </html>

The browser receives an HTML page.

2

document <html> <head> <title> Constructive &amp; Co.

<link> rel stylesheet href css/c01.css

It creates a model of the page and stores it in memory.

<body> <h1> Constructive &amp; Co.

<p> For all orders and inquiries please call

<em> 555-3344

OBJECT ELEMENT TEXT ATTRIBUTES

3 It shows the page on screen using a rendering engine.

THE ABC OF PROGRAMMING

41


SUMMARY THE ABC OF PROGRAMMING

B: How do computers fit in with the world around them?

42

SS

Computers create models of the world using data.

SS

The models use objects to represent physical things. Objects can have: properties that tell us about the object; methods that perform tasks using the properties of that object; events which are triggered when a user interacts with the computer.

SS

Programmers can write code to say â&#x20AC;&#x153;When this event occurs, run that code.â&#x20AC;?

SS

Web browsers use HTML markup to create a model of the web page. Each element creates its own node (which is a kind of object).

SS

To make web pages interactive, you write code that uses the browser's model of the web page.

THE ABC OF PROGRAMMING


1/c

HOW DO I WRITE A SCRIPT FOR A WEB PAGE?

THE ABC OF PROGRAMMING

43


HOW HTML, CSS, & JAVASCRIPT FIT TOGETHER Before diving into the JavaScript language, you need to know how it will fit together with the HTML and CSS in your web pages. Web developers usually talk about three languages that are used to create web pages: HTML, CSS, and JavaScript.

<html>

Where possible, aim to keep the three languages in separate files, with the HTML page linking to CSS and JavaScript files.

{css}

javascript()

CONTENT LAYER

PRESENTATION LAYER

BEHAVIOR LAYER

.html files

.css files

.js files

This is where the content of the page lives. The HTML gives the page structure and adds semantics.

The CSS enhances the HTML page with rules that state how the HTML content is presented (backgrounds, borders, box dimensions, colors, fonts, etc.).

This is where we can change how the page behaves, adding interactivity. We will aim to keep as much of our JavaScript as possible in separate files.

Programmers often refer to this as a separation of concerns.

44

Each language forms a separate layer with a different purpose. Each layer, from left to right, builds on the previous one.

THE ABC OF PROGRAMMING


PROGRESSIVE ENHANCEMENT These three layers form the basis of a popular approach to building web pages called progressive enhancement. As more and more web-enabled devices come onto the market, this concept is becoming more widely adopted.

It's not just screen sizes that are varied - connection speeds and capabilities of each device can also differ.

Also, some people browse with JavaScript turned off, so you need to make sure that the page still works for them.

HTML ONLY

HTML + CSS

HTML + CSS +JAVASCRIPT

Starting with the HTML layer allows you to focus on the most important thing about your site: its content.

Adding the CSS rules in a separate file keeps rules regarding how the page looks away from the content itself.

The JavaScript is added last and enhances the usability of the page or the experience of interacting with the site.

Being plain HTML, this layer should work on all kinds of devices, be accessible to all users, and load quite quickly on slow connections.

You can use the same style sheet with all of your site, making your sites faster to load and easier to maintain. Or you can use different style sheets with the same content to create different views of the same data.

Keeping it separate means that the page still works if the user cannot load or run the JavaScript. You can also reuse the code on several pages (making the site faster to load and easier to maintain).

THE ABC OF PROGRAMMING

45


CREATING A BASIC JAVASCRIPT JavaScript is written in plain text, just like HTML and CSS, so you do not need any new tools to write a script. This example adds a greeting into an HTML page. The greeting changes depending on the time of day. Create a folder to put the example in called c01, then start up your favorite code editor, and enter the text to the right. 1

A JavaScript file is just a text file (like HTML and CSS files are) but it has a .js file extension, so save this file with the name add-content.js Don't worry about what the code means yet, for now we will focus on how the script is created and how it fits with an HTML page.

var today = new Date(); var hourNow = today.getHours(); var greeting; if (hourNow > 18) { greeting = 'Good evening!'; } else if (hourNow > 12) { greeting = 'Good afternoon!'; } else if (hourNow > 0) { greeting = 'Good morning!'; } else { greeting = 'Welcome!'; } document.write('<h3>' + greeting

+ '</h3>');

2 Get the CSS and images for this example from the website that accompanies the book: www.javascriptbook.com

To keep the files organized, in the same way that CSS files often live in a folder called styles or css, your JavaScript files can live in a folder called scripts, javascript, or js. In this case, save your file in a folder called js

46

THE ABC OF PROGRAMMING

Here you can see the file structure that you will end up with when you finish the example. Always treat file names as being case-sensitive.


LINKING TO A JAVASCRIPT FILE FROM AN HTML PAGE When you want to use JavaScript with a web page, you use the HTML <script> element to tell the browser it is coming across a script. Its src attribute tells people where the JavaScript file is stored. <!DOCTYPE html> <html> <head> <title>Constructive &amp; Co.</title> <link rel="stylesheet" href="css/c01.css" /> </head> <body> <h1>Constructive &amp; Co.</h1> <script src="js/add-content.js"></script> <p>For all orders and inquiries please call <em>555-3344</em></p> </body> </html>

3 In your code editor, enter the HTML shown on the left. Save this file with the name add-content.html

The HTML <script> element is used to load the JavaScript file into the page. It has an attribute called src, whose value is the path to the script you created. This tells the browser to find and load the script file (just like the src attribute on an <img> tag).

4 Open the HTML file in your browser. You should see that the JavaScript has added a greeting (in this case, Good Afternoon!) to the page. (These greetings are coming from the JavaScript file; they are not in the HTML file.)

Please note: Internet Explorer sometimes prevents JavaScript running when you open a page stored on your hard drive. If this affects you, please try Chrome, Firefox, Opera, or Safari instead.

THE ABC OF PROGRAMMING

47


THE SOURCE CODE IS NOT AMENDED If you look at the source code for the example you just created, you will see that the HTML is still exactly the same. 5 Once you have tried the example in your browser, view the source code for the page. (This option is usually under the View, Tools or Develop menu of the browser.)

6 The source of the web page does not actually show the new element that has been added into the page; it just shows the link to the JavaScript file.

As you move through the book, you will see most of the scripts are added just before the closing </body> tag (this is often considered a better place to put your scripts).

48

THE ABC OF PROGRAMMING


PLACING THE SCRIPT IN THE PAGE You may see JavaScript in the HTML between opening <script> and closing </script> tags (but it is better to put scripts in their own files). <!DOCTYPE html> <html> <head> <title>Constructive &amp; Co.</title> <link rel="stylesheet" href="css/c01.css" /> </head> <body> <h1>Constructive &amp; Co.</h1> <script>document.write('<h3>Welcome!</h3>'); </script> <p>For all orders and inquiries please call <em>555-3344</em></p> </body> </html>

7 Finally, try opening the HTML file, removing the src attribute from the opening <script> tag, and adding the new code shown on the left between the opening <script> tag and the closing </script> tag. The src attribute is no longer needed because the JavaScript is in the HTML page.

As noted on p44, it is better not to mix JavaScript in your HTML pages like this, but it is mentioned here as you may come across this technique. 8 Open the HTML file in your web browser and the welcome greeting is written into the page.

As you may have guessed, document.write() writes content into the document (the web page). It is a simple way to add content to a page, but not always the best. Chapter 5 discusses various ways to update the content of a page.

THE ABC OF PROGRAMMING

49


HOW TO USE OBJECTS & METHODS This one line of JavaScript shows how to use objects and methods. Programmers refer to this as calling a method of an object.

The write() method of the document object allows new content to be written into the page where the <script> element sits.

The document object represents the entire web page. All web browsers implement this object, and you can use it just by giving its name. OBJECT

METHOD

document.write('Good afternoon!'); MEMBER OPERATOR

The document object has several methods and properties. They are known as members of that object.

Whenever a method requires some information in order to work, the data is given inside the parentheses.

You can access the members of an object using a dot between the object name and the member you want to access. It is called a member operator.

Each piece of information is called a parameter of the method. In this case, the write() method needs to know what to write into the page.

Behind the scenes, the browser uses a lot more code to make the words appear on the screen, but you don't need to know how the browser does this.

50

PARAMETERS

THE ABC OF PROGRAMMING

You only need to know how to call the object and method, and how to tell it the information it needs to do the job you want it to. It will do the rest.

There are lots of objects like the document object, and lots of methods like the write() method that will help you write your own scripts.


JAVASCRIPT RUNS WHERE IT IS FOUND IN THE HTML When the browser comes across a <script> element, it stops to load the script and then checks to see if it needs to do anything.

<!DOCTYPE html> <html> <head> <title>Constructive &amp; Co.</title> <link rel="stylesheet" href="css/c01.css" /> </head> <body> <h1>Constructive &amp; Co.</h1> <p>For all orders and inquiries please call <em>555-3344</em></p> <script src="js/add-content.js"></script> </body> </html> Note how the <script> element can be moved below the first paragraph, and this affects where the new greeting is written into the page.

This has implications for where <script> elements should be placed, and can affect the loading time of pages (see p356).

THE ABC OF PROGRAMMING

51


SUMMARY THE ABC OF PROGRAMMING

C: How do I write a script for a web page?

52

SS

It is best to keep JavaScript code in its own JavaScript file. JavaScript files are text files (like HTML pages and CSS style sheets), but they have the .js extension.

SS

The HTML <script> element is used in HTML pages to tell the browser to load the JavaScript file (rather like the <link> element can be used to load a CSS file).

SS

If you view the source code of the page in the browser, the JavaScript will not have changed the HTML, because the script works with the model of the web page that the browser has created.

THE ABC OF PROGRAMMING


CONTENTS

FOREWORD

xxvii

INTRODUCTION

xxix

CHAPTER 1: GETTING STARTED

1

A Quick Introduction to ASP.NET MVC

1

How ASP.NET MVC Fits in with ASP.NET The MVC Pattern MVC as Applied to Web Frameworks The Road to MVC 5 MVC 4 Overview Open-Source Release

2 2 3 3 6 10

ASP.NET MVC 5 Overview One ASP.NET New Web Project Experience ASP.NET Identity Bootstrap Templates Attribute Routing ASP.NET Scaffolding Authentication Filters Filter Overrides

Installing MVC 5 and Creating Applications Software Requirements for ASP.NET MVC 5 Installing ASP.NET MVC 5 Creating an ASP.NET MVC 5 Application The New ASP.NET Project Dialog

The MVC Application Structure ASP.NET MVC and Conventions Convention over Configuration Conventions Simplify Communication

Summary CHAPTER 2: CONTROLLERS

The Controller’s Role A Sample Application: The MVC Music Store

11 11 12 12 13 14 14 15 15

16 16 16 17 18

24 27 28 29

29 31

31 34


CONTENTS

Controller Basics A Simple Example: The Home Controller Writing Your First Controller Parameters in Controller Actions

Summary CHAPTER 3: VIEWS

The Purpose of Views View Basics Understanding View Conventions Strongly Typed Views How ViewBag Falls Short Understanding ViewBag, ViewData, and ViewDataDictionary

View Models Adding a View The Razor View Engine

39 42 45

47 49

50 50 54 55 55 57

58 60 63

What Is Razor? Code Expressions HTML Encoding Code Blocks Razor Syntax Samples Layouts ViewStart

63 64 66 68 68 70 72

Specifying a Partial View Summary

73 74

CHAPTER 4: MODELS

Modeling the Music Store Scaffolding a Store Manager What Is Scaffolding? Scaffolding and the Entity Framework Executing the Scaffolding Template Executing the Scaffolded Code

Editing an Album Building a Resource to Edit an Album Responding to the Edit POST Request

Model Binding The DefaultModelBinder Explicit Model Binding

Summary xviii

38

75

76 80 80 82 85 92

97 97 101

103 104 105

107


CONTENTS

CHAPTER 5: FORMS AND HTML HELPERS

Using Forms The Action and the Method To GET or to POST?

HTML Helpers Automatic Encoding Making Helpers Do Your Bidding Inside HTML Helpers Setting Up the Album Edit Form Adding Inputs Helpers, Models, and View Data Strongly Typed Helpers Helpers and Model Metadata Templated Helpers Helpers and ModelState

109

110 110 111

114 115 115 116 117 118 124 126 127 127 128

Other Input Helpers

129

Html.Hidden Html.Password Html.RadioButton Html.CheckBox

129 129 129 130

Rendering Helpers

130

Html.ActionLink and Html.RouteLink URL Helpers Html.Partial and Html.RenderPartial Html.Action and Html.RenderAction

Summary CHAPTER 6: DATA ANNOTATIONS AND VALIDATION

Annotating Orders for Validation Using Validation Annotations Custom Error Messages and Localization Looking Behind the Annotation Curtain Controller Actions and Validation Errors

131 132 133 133

135 137

138 141 146 147 148

Custom Validation Logic

150

Custom Annotations IValidatableObject

150 154

Display and Edit Annotations Display ScaffoldColumn DisplayFormat

155 155 156 156 xix


CONTENTS

ReadOnly DataType UIHint HiddenInput

Summary CHAPTER 7: MEMBERSHIP, AUTHORIZATION, AND SECURITY

Security: Not fun, But Incredibly Important Using the Authorize Attribute to Require Login Securing Controller Actions How AuthorizeAttribute Works with Forms Authentication and the AccountController Windows Authentication

Using AuthorizeAttribute to Require Role Membership Extending User Identity Storing additional user profile data Persistance control Managing users and roles

158 159

159 162 162 167 169

172 174 174 174 175

External Login via OAuth and OpenID

175

Registering External Login Providers Configuring OpenID Providers Configuring OAuth Providers Security Implications of External Logins

176 178 180 181

Understanding the Security Vectors in a Web Application Threat: Cross-Site Scripting Threat: Cross-Site Request Forgery Threat: Cookie Stealing Threat: Over-Posting Threat: Open Redirection

Proper Error Reporting and the Stack Trace Using Configuration Transforms Using Retail Deployment Configuration in Production Using a Dedicated Error Logging System

Security Recap and Helpful Resources Summary CHAPTER 8: AJAX

jQuery jQuery Features Unobtrusive JavaScript Using jQuery xx

157 157 158 158

182 183 193 197 200 202

207 208 209 209

209 211 213

214 214 218 219


CONTENTS

Ajax Helpers Adding the Unobtrusive Ajax Script to Your Project Ajax ActionLinks HTML 5 Attributes Ajax Forms

Client Validation jQuery Validation Custom Validation

Beyond Helpers jQuery UI Autocomplete with jQuery UI JSON and Client-Side Templates Bootstrap Plugins

Improving Ajax Performance Using Content Delivery Networks Script Optimizations Bundling and Minification

Summary CHAPTER 9: ROUTING

Uniform Resource Locators Introduction to Routing Comparing Routing to URL Rewriting Routing Approaches Defining Attribute Routes Defining Traditional Routes Choosing Attribute Routes or Traditional Routes Named Routes MVC Areas Catch-All Parameter Multiple Route Parameters in a Segment StopRoutingHandler and IgnoreRoute Debugging Routes

Inside Routing: How Routes Generate URLs High-Level View of URL Generation A Detailed Look at URL Generation Ambient Route Values More Examples of URL Generation with the Route Class

Inside Routing: How Routes Tie Your URL to an Action The High-Level Request Routing Pipeline RouteData

225 225 226 230 230

233 233 236

241 242 243 246 251

253 253 253 254

255 257

258 259 259 260 260 271 280 280 282 284 285 286 286

288 288 289 291 293

294 294 295 xxi


CONTENTS

Custom Route Constraints Using Routing with Web Forms Summary CHAPTER 10: NUGET

Introduction to NuGet Adding a Library as a Package Finding Packages Installing a Package Updating a Package Package Restore Using the Package Manager Console

Creating Packages Packaging a Project Packaging a Folder Configuration File and Source Code Transformations NuSpec File Metadata Dependencies Specifying Files to Include Tools Framework and Profile Targeting Prerelease Packages

Publishing Packages Publishing to NuGet.org Using NuGet.exe Using the Package Explorer

Summary

299

299 301 301 303 308 308 309

312 313 313 314 315 316 317 318 319 322 324

325 325 327 330

332

CHAPTER 11: ASP.NET WEB API

333

Defining ASP.NET Web API Getting Started with Web API Writing an API Controller

334 335 335

Examining the Sample ValuesController Async by Design: IHttpController Incoming Action Parameters Action Return Values, Errors, and Asynchrony

Configuring Web API Configuration in Web-Hosted Web API Configuration in Self-Hosted Web API xxii

295 296 297

335 336 340 340

342 343 343


CONTENTS

Adding Routes to Your Web API Binding Parameters Filtering Requests Enabling Dependency Injection Exploring APIs Programmatically Tracing the Application Web API Example: ProductsController Summary CHAPTER 12: SINGLE PAGE APPLICATIONS WITH ANGULARJS

Understanding and Setting Up AngularJS Whatâ&#x20AC;&#x2122;s AngularJS? Your Goal in This Chapter Getting Started Adding AngularJS to the Site Setting Up the Database

Building the Web API Building Applications and Modules Creating Controllers, Models, and Views Services Routing Details View A Custom MovieService Deleting Movies Editing and Creating Movies

Summary CHAPTER 13: DEPENDENCY INJECTION

Software Design Patterns Design Pattern: Inversion of Control Design Pattern: Service Locator Design Pattern: Dependency Injection

Dependency Resolution in MVC

346 347 349 350 350 352 352 354 355

356 356 356 357 359 361

363 364 365 368 371 373 375 377 379

384 385

385 386 388 392

395

Singly Registered Services in MVC Multiply Registered Services in MVC Arbitrary Objects in MVC

397 397 399

Dependency Resolution in Web API

402

Singly Registered Services in Web API Multiply Registered Services in Web API

402 403 xxiii


CONTENTS

Arbitrary Objects in Web API Dependency Resolvers in MVC vs. Web API

Summary CHAPTER 14: UNIT TESTING

Understanding Unit Testing and Test-Driven Development Defining Unit Testing Defining Test-Driven Development

Building a Unit Test Project Examining the Default Unit Tests Test Only the Code You Write

Advice for Unit Testing Your ASP.NET MVC and ASP.NET Web API Applications Testing Controllers Testing Routes Testing Validators

Summary CHAPTER 15: EXTENDING MVC

Extending Models Turning Request Data into Models Describing Models with Metadata Validating Models

Extending Views Customizing View Engines Writing HTML Helpers Writing Razor Helpers

Extending Controllers Selecting Actions Filters Providing Custom Results

Summary CHAPTER 16: ADVANCED TOPICS

Mobile Support Adaptive Rendering Display Modes

Advanced Razor Templated Razor Delegates View Compilation xxiv

405 405

405 407

408 408 410

412 413 415

415 416 420 423

427 429

430 430 436 438

442 442 444 445

446 446 447 457

458 461

461 462 470

473 473 474


CONTENTS

Advanced View Engines Configuring a View Engine Finding a View The View Itself Alternative View Engines New View Engine or New ActionResult?

Advanced Scaffolding Introducing ASP.NET Scaffolding Customizing Scaffold Templates Custom Scaffolders

476 477 478 479 480 482

482 482 483 485

Advanced Routing

486

RouteMagic Editable Routes

486 487

Advanced Templates The Default Templates Custom Templates

Advanced Controllers Defining the Controller: The IController Interface The ControllerBase Abstract Base Class The Controller Class and Actions Action Methods The ActionResult Action Invoker Using Asynchronous Controller Actions

Summary

492 492 496

498 498 499 500 502 502 511 515

520

CHAPTER 17: REAL-WORLD ASP.NET MVC: BUILDING THE NUGET.ORG WEBSITE

521

May the Source Be with You WebActivator ASP.NET Dynamic Data Exception Logging Profiling Data Access EF Code–Based Migrations Deployments with Octopus Deploy Automated Browser Testing with Fluent Automation Other Useful NuGet Packages

522 526 527 530 532 535 536 539 540 541

WebBackgrounder Lucene.NET

541 542

xxv


CONTENTS

AnglicanGeek.MarkdownMailer Ninject

Summary APPENDIX: ASP.NET MVC 5.1

ASP.NET MVC 5.1 Release Description

544 545

545

Getting MVC 5.1 Upgrading MVC 5 Projects from MVC 5.1 Upgrading an MVC 5 Application to 5.1

546 546 547

Enum Support in ASP.NET MVC Views Attribute Routing with Custom Constraints

549 553

Route Constraints in Attribute Routing ASP.NET MVC 5.1 Example: Adding a Custom LocaleRoute

Bootstrap and JavaScript Enhancements EditorFor Now Supports Passing HTML Attributes Client-Side Validation for MinLength and MaxLength Three Small but Useful Fixes to MVC Ajax Support

Summary INDEX

xxvi

543 543

554 554

558 558 561 562

563 565


1 —by Jon Galloway

WHAT’S IN THIS CHAPTER? ➤

Understanding ASP.NET MVC

An overview of ASP.NET MVC 5

How to create MVC 5 applications

How MVC applications are structured

This chapter gives you a quick introduction to ASP.NET MVC, explains how ASP.NET MVC 5 fits into the ASP.NET MVC release history, summarizes what’s new in ASP.NET MVC 5, and shows you how to set up your development environment to build ASP.NET MVC 5 applications. This is a Professional Series book about a version 5 web framework, so we keep the introductions short. We’re not going to spend any time convincing you that you should learn ASP.NET MVC. We assume that you’ve bought this book for that reason, and that the best proof of software frameworks and patterns is in showing how they’re used in real-world scenarios.

A QUICK INTRODUCTION TO ASP.NET MVC ASP.NET MVC is a framework for building web applications that applies the general ModelView-Controller pattern to the ASP.NET framework. Let’s break that down by fi rst looking at how ASP.NET MVC and the ASP.NET framework are related.


2

CHAPTER 1 GETTING STARTED

How ASP.NET MVC Fits in with ASP.NET When ASP.NET 1.0 was fi rst released in 2002, it was easy to think of ASP.NET and Web Forms as one and the same thing. ASP.NET has always supported two layers of abstraction, though: ➤

System.Web.UI: The Web Forms layer, comprising server controls, ViewState, and so on

System.Web: The plumbing, which supplies the basic web stack, including modules, han-

dlers, the HTTP stack, and so on The mainstream method of developing with ASP.NET included the whole Web Forms stack—taking advantage of drag-and-drop server controls and semi-magical statefulness, while dealing with the complications behind the scenes (an often confusing page lifecycle, less than optimal HTML that was difficult to customize, and so on). However, there was always the possibility of getting below all that—responding directly to HTTP requests, building out web frameworks just the way you wanted them to work, crafting beautiful HTML—using handlers, modules, and other handwritten code. You could do it, but it was painful; there just wasn’t a built-in pattern that supported any of those things. It wasn’t for lack of patterns in the broader computer science world, though. By the time ASP.NET MVC was announced in 2007, the MVC pattern was becoming one of the most popular ways of building web frameworks.

The MVC Pattern Model-View-Controller (MVC) has been an important architectural pattern in computer science for many years. Originally named Thing-Model-View-Editor in 1979, it was later simplified to ModelView-Controller. r It is a powerful and elegant means of separating concerns within an application (for example, separating data access logic from display logic) and applies itself extremely well to web applications. Its explicit separation of concerns does add a small amount of extra complexity to an application’s design, but the extraordinary benefits outweigh the extra effort. It has been used in dozens of frameworks since its introduction. You’ll fi nd MVC in Java and C++, on Mac and on Windows, and inside literally dozens of frameworks. The MVC separates the user interface (UI) of an application into three main aspects: ➤

The Model: A set of classes that describes the data you’re working with as well as the business rules for how the data can be changed and manipulated

The View: Defines how the application’s UI will be displayed

The Controller: A set of classes that handles communication from the user, overall application flow, and application-specific logic

MVC AS A USER INTERFACE PATTERN Notice that we’ve referred to MVC as a pattern for the UI. The MVC pattern presents a solution for handling user interaction, but says nothing about how you will handle other application concerns like data access, service interactions, and so on. It’s helpful to keep this in mind as you approach MVC: It is a useful pattern, but likely one of many patterns you will use in developing an application.


A Quick Introduction to ASP.NET MVC

MVC as Applied to Web Frameworks The MVC pattern is used frequently in web programming. With ASP.NET MVC, it’s translated roughly as: ➤

Models: These are the classes that represent the domain you are interested in. These domain objects often encapsulate data stored in a database as well as code that manipulates the data and enforces domain-specific business logic. With ASP.NET MVC, this is most likely a Data Access Layer of some kind, using a tool like Entity Framework or NHibernate combined with custom code containing domain-specific logic.

View: This is a template to dynamically generate HTML. We cover more on that in Chapter 3 when we dig into views.

Controller: This is a special class that manages the relationship between the View and the Model. It responds to user input, talks to the Model, and decides which view to render (if any). In ASP.NET MVC, this class is conventionally denoted by the suffix Controller.

NOTE It’s important to keep in mind that MVC is a high-level architectural

pattern, and its application varies depending on use. ASP.NET MVC is contextualized both to the problem domain (a stateless web environment) and the host system (ASP.NET). Occasionally I talk to developers who have used the MVC pattern in very different environments, and they get confused, frustrated, or both (confustrated?) because they assume that ASP.NET MVC works the exact same way it worked in their mainframe account processing system 15 years ago. It doesn’t, and that’s a good thing—ASP.NET MVC is focused on providing a great web development framework using the MVC pattern and running on the .NET platform, and that contextualization is part of what makes it great. ASP.NET MVC relies on many of the same core strategies that the other MVC platforms use, plus it offers the benefits of compiled and managed code and exploits newer .NET language features, such as lambdas and dynamic and anonymous types. At its heart, though, ASP.NET applies the fundamental tenets found in most MVC-based web frameworks: ➤

Convention over configuration

Don’t repeat yourself (also known as the “DRY” principle)

Pluggability wherever possible

Try to be helpful, but if necessary, get out of the developer’s way

The Road to MVC 5 In the five years since ASP.NET MVC 1 was released in March 2009, we’ve seen five major releases of ASP.NET MVC and several more interim releases. To understand ASP.NET MVC 5, it’s

❘ 3


4

CHAPTER 1 GETTING STARTED

important to understand how we got here. This section describes the contents and background of each of the three major ASP.NET MVC releases.

DON’T PANIC! We list some MVC-specific features in this section that might not all make sense to you if you’re new to MVC. Don’t worry! We explain some context behind the MVC 5 release, but if this doesn’t all make sense, you can just skim or even skip until the “Creating an MVC 5 Application” section. We’ll get you up to speed in the following chapters.

ASP.NET MVC 1 Overview In February 2007, Scott Guthrie (“ScottGu”) of Microsoft sketched out the core of ASP.NET MVC while flying on a plane to a conference on the East Coast of the United States. It was a simple application, containing a few hundred lines of code, but the promise and potential it offered for parts of the Microsoft web developer audience was huge. As the legend goes, at the Austin ALT.NET conference in October 2007 in Redmond, Washington, ScottGu showed a group of developers “this cool thing I wrote on a plane” and asked whether they saw the need and what they thought of it. It was a hit. In fact, many people were involved with the original prototype, codenamed Scalene. Eilon Lipton e-mailed the fi rst prototype to the team in September 2007, and he and ScottGu bounced prototypes, code, and ideas back and forth. Even before the official release, it was clear that ASP.NET MVC wasn’t your standard Microsoft product. The development cycle was highly interactive: There were nine preview releases before the official release, unit tests were made available, and the code shipped under an open-source license. All these highlighted a philosophy that placed a high value on community interaction throughout the development process. The end result was that the official MVC 1.0 release—including code and unit tests—had already been used and reviewed by the developers who would be using it. ASP.NET MVC 1.0 was released on March 13, 2009.

ASP.NET MVC 2 Overview ASP.NET MVC 2 was released just one year later, in March 2010. Some of the main features in MVC 2 included: ➤

UI helpers with automatic scaffolding with customizable templates

Attribute-based model validation on both the client and server

Strongly typed HTML helpers

Improved Visual Studio tooling


A Quick Introduction to ASP.NET MVC

❘ 5

It also had lots of API enhancements and “pro” features, based on feedback from developers building a variety of applications on ASP.NET MVC 1, such as: ➤

Support for partitioning large applications into areas

Asynchronous controllers support

Support for rendering subsections of a page/site using Html.RenderAction

Lots of new helper functions, utilities, and API enhancements

One important precedent set by the MVC 2 release was that there were very few breaking changes. I think this is a testament to the architectural design of ASP.NET MVC, which allows for a lot of extensibility without requiring core changes.

ASP.NET MVC 3 Overview ASP.NET MVC 3 shipped just 10 months after MVC 2, driven by the release date for Web Matrix. Some of the top features in MVC 3 included: ➤

The Razor view engine

Support for .NET 4 Data Annotations

Improved model validation

Greater control and flexibility with support for dependency resolution and global action filters

Better JavaScript support with unobtrusive JavaScript, jQuery Validation, and JSON binding

Use of NuGet to deliver software and manage dependencies throughout the platform

Razor is the fi rst major update to rendering HTML since ASP.NET 1 shipped almost a decade ago. The default view engine used in MVC 1 and 2 was commonly called the Web Forms view engine, because it uses the same ASPX/ASCX/MASTER fi les and syntax used in Web Forms. It works, but it was designed to support editing controls in a graphical editor, and that legacy shows. An example of this syntax in a Web Forms page is shown here: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits= "System.Web.Mvc.ViewPage<MvcMusicStore.ViewModels.StoreBrowseViewModel>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Browse Albums </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <div class="genre">


6

CHAPTER 1 GETTING STARTED

<h3><em><%: Model.Genre.Name %></em> Albums</h3> <ul id="album-list"> <% foreach (var album in Model.Albums) { %> <li> <a href="<%: Url.Action("Details", new { id = album.AlbumId }) %>"> <img alt="<%: album.Title %>" src="<%: album.AlbumArtUrl %>" /> <span><%: album.Title %></span> </a> </li> <% } %> </ul> </div> </asp:Content>

Razor was designed specifically as a view engine syntax. It has one main focus: code-focused templating for HTML generation. Here’s how that same markup would be generated using Razor: @model MvcMusicStore.Models.Genre @{ViewBag.Title = "Browse Albums";} <div class="genre"> <h3><em>@Model.Name</em> Albums</h3> <ul id="album-list"> @foreach (var album in Model.Albums) { <li> <a href="@Url.Action("Details", new { id = album.AlbumId })"> <img alt="@album.Title" src="@album.AlbumArtUrl" /> <span>@album.Title</span> </a> </li> } </ul> </div>

The Razor syntax is easier to type, and easier to read. Razor doesn’t have the XML-like heavy syntax of the Web Forms view engine. We talk about Razor in a lot more depth in Chapter 3.

MVC 4 Overview The MVC 4 release built on a pretty mature base and is able to focus on some more advanced scenarios. Some top features include: ➤

ASP.NET Web API

Enhancements to default project templates


A Quick Introduction to ASP.NET MVC

Mobile project template using jQuery Mobile

Display modes

Task support for asynchronous controllers

Bundling and minification

❘ 7

Because MVC 4 is still a pretty recent release, we explain a few of these features in a little more detail here and describe them in more detail throughout the book.

ASP.NET Web API ASP.NET MVC was designed for creating websites. Throughout the platform are obvious design decisions that indicate the assumed usage: responding to requests from browsers and returning HTML. However, ASP.NET MVC made it really easy to control the response down to the byte, and the MVC pattern was useful in creating a service layer. ASP.NET developers found that they could use it to create web services that returned XML, JSON, or other non-HTML formats, and it was a lot easier than grappling with other service frameworks, such as Windows Communication Foundation (WCF), or writing raw HTTP handlers. It still had some quirks, as you were using a website framework to deliver services, but many found that it was better than the alternatives. MVC 4 included a better solution: ASP.NET Web API (referred to as Web API), a framework that offers the ASP.NET MVC development style but is tailored to writing HTTP services. This includes both modifying some ASP.NET MVC concepts to the HTTP service domain and supplying some new service-oriented features. Here are some of the Web API features that are similar to MVC, just adapted for the HTTP service domain: ➤

Routing: ASP.NET Web API uses the same routing system for mapping URLs to controller actions. It contextualizes the routing to HTTP services by mapping HTTP verbs to actions by convention, which both makes the code easier to read and encourages following RESTful service design.

Model binding and validation: Just as MVC simplifies the process of mapping input values (form fields, cookies, URL parameters, and so on) to model values, Web API automatically maps HTTP request values to models. The binding system is extensible and includes the same attribute-based validation that you use in MVC model binding.

Filters: MVC uses filters (discussed in Chapter 15) to allow for adding behaviors to actions via attributes. For instance, adding an [Authorize] attribute to an MVC action will prohibit anonymous access, automatically redirecting to the login page. Web API also supports some


8

CHAPTER 1 GETTING STARTED

of the standard MVC filters (like a service-optimized [Authorize] attribute) and custom filters. ➤

Scaffolding: You add new Web API controllers using the same dialog used to add an MVC controller (as described later this chapter). You have the option to use the Add Controller dialog to quickly scaffold a Web API controller based on an Entity Framework– based model type.

Easy unit testability: Much like MVC, Web API is built around the concepts of dependency injection and avoiding the use of global state.

Web API also adds some new concepts and features specific to HTTP service development: ➤

HTTP programming model: The Web API development experience is optimized for working with HTTP requests and responses. There’s a strongly typed HTTP object model, HTTP status codes and headers are easily accessible, and so on.

Action dispatching based on HTTP verbs: In MVC the dispatching of action methods is based on their names. In Web API, methods can be automatically dispatched based on the HTTP verb. So, for example, a GET request would be automatically dispatched to a controller action named GetItem.

Content negotiation: HTTP has long supported a system of content negotiation, in which browsers (and other HTTP clients) indicate their response format preferences, and the server responds with the highest preferred format that it can support. This means that your controller can supply XML, JSON, and other formats (you can add your own), responding to whichever the client most prefers. This allows you to add support for new formats without having to change any of your controller code.

Code-based configuration: Service configuration can be complex. Unlike WCF’s verbose and complex configuration file approach, Web API is configured entirely via code.

Although ASP.NET Web API is included with MVC, it can be used separately. In fact, it has no dependencies on ASP.NET at all, and can be self-hosted—that is, hosted outside of ASP.NET and IIS. This means you can run Web API in any .NET application, including a Windows Service or even a simple console application. For a more detailed look at ASP.NET Web API, see Chapter 11.

NOTE As described previously, MVC and Web API have a lot in common

(model-controller patterns, routing, filters, etc.). Architectural reasons dictated that they would be separate frameworks which shared common models and paradigms in MVC 4 and 5. For example, MVC has maintained compatibility and a common codebase (e.g. the System.Web’s HttpContext) with ASP.NET, which didn’t fit the long term goals of Web API. However, in May 2014 the ASP.NET team announced their plans to merge MVC, Web API and Web Pages in MVC 6. This next release is part of what is being called ASP.NET vNext, which is planned to run on a “cloud optimized” version of the .NET Framework. These framework changes provide a good


A Quick Introduction to ASP.NET MVC

opportunity to move MVC beyond System.Web, which means it can more easily merge with Web API to form a next generation web stack. The goal is to support MVC 5 with minimal breaking changes. The.NET Web Development and Tools blog announcement post lists some of these plans as follows: ➤

MVC, Web API, and Web Pages will be merged into one framework, called MVC 6. MVC 6 has no dependency on System.Web.

ASP.NET vNext includes new cloud-optimized versions of MVC 6, SignalR 3, and Entity Framework 7.

ASP.NET vNext will support true side-by-side deployment for all dependencies, including .NET for cloud. Nothing will be in the GAC.

ASP.NET vNext is host-agnostic. You can host your app in IIS, or self-host in a custom process.

Dependency injection is built into the framework.

Web Forms, MVC 5, Web API 2, Web Pages 3, SignalR 2, EF 6 will be fully supported on ASP.NET vNext.

.NET vNext (Cloud Optimized) will be a subset of the .NET vNext Framework, optimized for cloud and server workloads.

MVC 6, SignalR 3, EF 7 will have some breaking changes: ➤

New project system

New configuration system

MVC / Web API / Web Pages merge, using a common set of abstractions for HTTP, routing, action selection, filters, model binding, and so on

No System.Web, new lightweight HttpContext

For more information, see: http://blogs.msdn.com/b/webdev/ archive/2014/05/13/asp-net-vnext-the-future-of-net-on-the-server .aspx.

Display Modes Display modes use a convention-based approach to allow selecting different views based on the browser making the request. The default view engine fi rst looks for views with names ending with .Mobile.cshtml when the browser’s user agent indicates a known mobile device. For example, if you have a generic view titled Index.cshtml and a mobile view titled Index.Mobile.cshtml, MVC 5 automatically uses the mobile view when viewed in a mobile browser. Although the default determination of mobile browsers is based on user agent detection, you can customize this logic by registering your own custom device modes.

❘ 9


10

CHAPTER 1 GETTING STARTED

You fi nd out more about Display modes in the mobile web discussion in Chapter 16.

Bundling and Minification ASP.NET MVC 4 (and later) supports the same bundling and minification framework included in ASP.NET 4.5. This system reduces requests to your site by combining several individual script references into a single request. It also “minifies” the requests through a number of techniques, such as shortening variable names and removing whitespace and comments. This system works on CSS as well, bundling CSS requests into a single request and compressing the size of the CSS request to produce equivalent rules using a minimum of bytes, including advanced techniques like semantic analysis to collapse CSS selectors. The bundling system is highly configurable, enabling you to create custom bundles that contain specific scripts and reference them with a single URL. You can see some examples by referring to default bundles listed in /App_Start/BundleConfig.cs in a new MVC 5 application using the Internet template. One nice byproduct of using bundling and minification is that you can remove fi le references from your view code. This means that you can add or upgrade script libraries and CSS fi les that have different fi lenames without having to update your views or layout, because the references are made to script and CSS bundles instead of individual fi les. For example, the MVC Internet application template includes a jQuery bundle that is not tied to the version number: bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js"));

This is then referenced in the site layout ( _Layout.cshtml) by the bundle URL, as follows: @Scripts.Render("~/bundles/jquery")

Because these references aren’t tied to a jQuery version number, updating the jQuery library (either manually or via NuGet) is picked up automatically by the bundling and minification system without requiring any code changes.

Open-Source Release ASP.NET MVC has been under an open-source license since the initial release, but it was just opensource code instead of a full open-source project. You could read the code; you could modify code; you could even distribute your modifications; but you couldn’t contribute your code back to the official MVC code repository. That changed with the ASP.NET Web Stack open-source announcement in May 2012. This announcement marked the transition of ASP.NET MVC, ASP.NET Web Pages (including the Razor view engine), and ASP.NET Web API from open-source licensed code to fully open-source projects. All code changes and issue tracking for these projects is done in public code repositories, and these projects are allowed to accept community code contributions (also known as pull requests) if the team agrees that the changes make sense. Even in the short time since the project has been opened, several bug fi xes and feature enhancements have already been accepted into the official source and shipped with the MVC 5 release. External


ASP.NET MVC 5 Overview

❘ 11

code submissions are reviewed and tested by the ASP.NET team, and when released Microsoft will support them just as they have any of the previous ASP.NET MVC releases. Even if you’re not planning to contribute any source code, the public repository makes a huge difference in visibility. Although in the past you needed to wait for interim releases to see what the team was working on, you can now view source check-ins as they happen (at http://aspnetwebstack .codeplex.com/SourceControl/list/changesets) and even run nightly releases of the code to test out new features as they’re written.

ASP.NET MVC 5 OVERVIEW MVC 5 was released along with Visual Studio 2013 in October 2013. The main focus of this release was on a “One ASP.NET” initiative (described in the following sections) and core enhancements across the ASP.NET frameworks. Some of the top features include: ➤

One ASP.NET

New Web Project Experience

ASP.NET Identity

Bootstrap templates

Attribute Routing

ASP.NET scaffolding

Authentication filters

Filter overrides

One ASP.NET Options are nice. Web applications vary quite a bit, and web tools and platforms are not “one size fits all.” On the other hand, some choices can be paralyzing. We don’t like having to choose one thing if it means giving up something else. This applies doubly to choices at the beginning of a project: I’m just getting started; I have no idea what this project will require a year down the line! In previous versions of MVC, you were faced with a choice every time you created a project. You had to choose between an MVC application, Web Forms application, or some other project type. After you had made your decision, you were essentially trapped. You could kind of add Web Forms to an MVC application, but adding MVC to a Web Forms application was difficult. MVC applications had a special project type GUID hidden in their csproj fi le, and that was just one of the mysterious changes you had to make when attempting to add MVC to Web Forms applications. In MVC 5, that all goes away, because just one ASP.NET project type exists. When you create a new web application in Visual Studio 2013, there’s no difficult choice, just a Web application. This isn’t just supported when you fi rst create an ASP.NET project; you can add in support for other frameworks as you develop, because the tooling and features are delivered as NuGet packages. For


12

CHAPTER 1 GETTING STARTED

example, if you change your mind later on, you can use ASP.NET Scaffolding to add MVC to any existing ASP.NET application.

New Web Project Experience As part of the new One ASP.NET experience, the dialogs for creating a new MVC application in Visual Studio 2013 have been merged and simplified. You fi nd out more about the new dialogs later in this chapter, in the section titled “Creating an MVC 5 Application.”

ASP.NET Identity The membership and authentication systems in MVC 5 have been completely rewritten as part of the new ASP.NET Identity system. This new system moves beyond some outdated constraints of the previous ASP.NET Membership system, while adding some sophistication and configurability to the Simple Membership system that shipped with MVC 4. Here are some of the top new features in ASP.NET Identity: ➤

One ASP.NET Identity system: In support of the One ASP.NET focus we discussed earlier, the new ASP.NET Identity was designed to work across the ASP.NET family (MVC, Web Forms, Web Pages, Web API, SignalR, and hybrid applications using any combination).

Control over user profile data: Although it’s a frequently used application for storing additional, custom information about your users, the ASP.NET Membership system made doing it very difficult. ASP.NET Identity makes storing additional user information (for example, account numbers, social media information, and contact address) as easily as adding properties to the model class that represents the user.

Control over persistence: By default, all user information is stored using Entity Framework Code First. This gives you both the simplicity and control you’re used to with Entity Framework Code First. However, you can plug in any other persistence mechanism you want, including other ORMs, databases, your own custom web services, and so on.

Testability: The ASP.NET Identity API was designed using interfaces. These allow you to write unit tests for your user-related application code.

Claims Based: Although ASP.NET Identity continues to offer support for user roles, it also supports claims-based authentication. Claims are a lot more expressive than roles, so this gives you a lot more power and flexibility. Whereas role membership is a simple Boolean value (a user either is or isn’t in the Administrator role), a user claim can carry rich information, such as a user’s membership level or identity specifics.

Login providers: Rather than just focusing on username / password authentication, ASP.NET Identity understands that users often are authenticated through social providers (for example, Microsoft Account, Facebook, or Twitter) and Windows Azure Active Directory.


ASP.NET MVC 5 Overview

❘ 13

NuGet distribution: ASP.NET Identity is installed in your applications as a NuGet package. This means you can install it separately, as well as upgrade to newer releases with the simplicity of updating a single NuGet package.

We’ll discuss ASP.NET Identity in more detail in Chapter 7.

Bootstrap Templates The visual design of the default template for MVC 1 projects had gone essentially unchanged through MVC 3. When you created a new MVC project and ran it, you got a white square on a blue background, as shown in Figure 1-1. (The blue doesn’t show in this black and white book, but you get the idea.)

FIGURE 1-1

In MVC 4, both the HTML and CSS for the default templates were redesigned to look somewhat presentable out of the box. They also work well in different screen resolutions. However, the HTML and CSS in the MVC 4 default templates were all custom, which wasn’t ideal. Visual design updates were tied to the MVC product release cycle, and you couldn’t easily share design templates with the broader web development community. In MVC 5, the project templates moved to run on the popular Bootstrap framework. Bootstrap was fi rst created by a developer and a designer at Twitter, who later split off to focus on Bootstrap completely. The default design for MVC 5 actually looks like something you might deploy to production, as shown in Figure 1-2.


14

â?&#x2DC;

CHAPTER 1 GETTING STARTED

FIGURE 1-2

Whatâ&#x20AC;&#x2122;s even nicer is that, because the Bootstrap framework has broad acceptance across the web developer community, a large variety of Bootstrap themes (both free and paid) are available from sites like http://wrapbootstrap.com and http://bootswatch.com. For example, Figure 1-3 shows a default MVC 5 application using the free Slate theme from Bootswatch. Chapter 16 covers Bootstrap in more detail, when you look at optimizing your MVC applications for mobile web browsers.

Attribute Routing Attribute Routingg is a new option for specifying routes by placing annotations on your controller classes or action methods. It was made possible due to an open source contribution from the popular AttributeRouting project (http://attributerouting.net). Chapter 9 describes Attribute Routing in detail.

ASP.NET Scaffolding Scaffoldingg is the process of generating boilerplate code based on your model classes. MVC has had scaffolding since version 1, but it was limited to MVC projects. The new ASP.NET scaffolding


ASP.NET MVC 5 Overview

â?&#x2DC; 15

system works in any ASP.NET application. Additionally, it includes support for building powerful custom scaffolders, complete with custom dialogs and a comprehensive scaffolding API. Chapters 3 and 4 describe scaffolding basics, and Chapter 16 explains two ways you can extend the scaffolding system.

FIGURE 1-3

Authentication Filters MVC has long supported a feature called authorization fi lters, which allow you to restrict access to a controller or action based on role membership or other custom logic. However, as discussed in Chapter 7, thereâ&#x20AC;&#x2122;s an important distinction between authentication (determining who a user is) and authorization (what an authenticated user is allowed to do). The newly added authentication fi lters execute before the authorize fi lter, allowing you to access the user claims that ASP.NET Identity provides and to run your own custom authentication logic. Chapter 15 covers authentication fi lters in detail.

Filter Overrides Filters are an advanced MVC feature that allow the developer to participate in the action and result execution pipeline. Filter overrides mean that you can exclude a controller or actions from executing a global fi lter.


16

CHAPTER 1 GETTING STARTED

Chapter 15 describes fi lters in detail, including fi lter overrides.

INSTALLING MVC 5 AND CREATING APPLICATIONS The best way to learn about how MVC 5 works is to get started by building an application, so let’s do that.

Software Requirements for ASP.NET MVC 5 MVC 5 requires .NET 4.5. As such, it runs on the following Windows client operating systems: ➤

Windows Vista SP2

Windows 7

Windows 8

It runs on the following server operating systems: ➤

Windows Server 2008 R2

Windows Server 2012

Installing ASP.NET MVC 5 After ensuring you’ve met the basic software requirements, it’s time to install ASP.NET MVC 5 on your development and production machines. Fortunately, that’s pretty simple.

SIDE-BY-SIDE INSTALLATION WITH PREVIOUS VERSIONS OF MVC MVC 5 installs side-by-side with previous versions of MVC, so you can install and start using MVC 5 right away. You’ll still be able to create and update existing applications running on previous versions.

Installing the MVC 5 Development Components The developer tooling for ASP.NET MVC 5 supports Visual Studio 2012 and Visual Studio 2013, including the free Express versions of both products. MVC 5 is included with Visual Studio 2013, so there’s nothing to install. If you’re using Visual Studio 2012, you can install MVC 5 support using this installer: http://www.microsoft.com/ en-us/download/41532. Note that all screenshots in this book show Visual Studio 2013 rather than Visual Studio 2012.

Server Installation MVC 5 is completely bin deployed, meaning that all necessary assemblies are included in the bin directory of your application. As long as you have .NET 4.5 on your server, you’re set.


Installing MVC 5 and Creating Applications

❘ 17

Creating an ASP.NET MVC 5 Application You can create a new MVC 5 application using either Visual Studio 2013 or Visual Studio 2013 Express for Web 2013. The experience in both IDEs is very similar; because this is a Professional Series book we focus on Visual Studio development, mentioning Visual Web Developer only when there are significant differences.

MVC MUSIC STORE We loosely base some of our samples on the MVC Music Store tutorial. This tutorial is available online at http://mvcmusicstore.codeplex.com and includes an e-book tutorial covering the basics of building an MVC application. We go quite a bit further than the basics in this book, but having a common base is nice if you need more information on the introductory topics.

To create a new MVC project:

1.

Choose File ➪ New Project, as shown in Figure 1-4.

FIGURE 1-4

2.

In the Installed Templates section in the left column of the New Project dialog, shown in Figure 1-5, select the Visual C# ➪ Web templates list. A list of web application types appears in the center column.


18

CHAPTER 1 GETTING STARTED

FIGURE 1-5

3.

Select ASP.NET Web Application, name your application MvcMusicStore, and click OK.

ONE ASP.NET PROJECT TEMPLATE Note that there isn’t an MVC project type; there’s just an ASP.NET Web Application. Whereas previous versions of Visual Studio and ASP.NET used a different project type for MVC, in Visual Studio 2013 they’ve been united into one common project type.

The New ASP.NET Project Dialog After you create a new MVC 5 application, the New ASP.NET Project dialog appears, as shown in Figure 1-6. This presents common options for all ASP.NET applications: ➤

Select a template

Add framework-specific folders and core references

Add unit tests


Installing MVC 5 and Creating Applications

Configure authentication

Windows Azure (Visual Studio 2013.2 and later)

❘ 19

FIGURE 1-6

The fi rst two selections (Select a Template and Add Folders and Core References For) work together. The template selects the starting point, but then you can use the framework checkboxes to add support for Web Forms, MVC, and Web API. This means you can select an MVC template and add in Web Forms support, or select an Empty template and add in support for any of the frameworks. That capability extends beyond new project creation; you can add in support for any of the frameworks at any time, because the framework folders and core references are added via NuGet packages. Remember the discussion in the earlier “One ASP.NET” section: Template and core reference selections are options, not hard choices. They’ll help you get started, but they won’t lock you in.

Selecting an Application Template Because you can use the Add Folders and Core References For option on any project, why do you need anything more than an Empty template? Well, the application templates give you a little more of a start by setting up some common things (as described in the list that follows) for a “mostly


20

CHAPTER 1 GETTING STARTED

MVC,” “mostly Web API,” or “mostly Web Forms” application. This section reviews those templates now. Remember, though, they’re just conveniences in Visual Studio 2013 rather than requirements; you could start with an Empty template and add in MVC support two weeks later by adding the NuGet packages. ➤

MVC: Let’s start with this template, because it’s the one you’ll use the most. The MVC template sets up a standard home controller with a few views, configures the site layout, and includes an MVC-specific Project_Readme.html page. The next section digs into this in a lot more detail.

Empty: As you would expect, the empty template sets you up with an empty project skeleton. You get a web.config (with some default website configuration settings) and a few assembly references you’ll need to get started, but that’s it. There’s no code, no JavaScript includes or CSS, not even a static HTML file. You can’t run an empty project until you put something in it. The empty template is for people who want to start completely from scratch.

Web Forms: The Web Forms template sets you up for ASP.NET Web Forms development.

NOTE You can learn more about Web Forms development in the Wrox book

titled Professional ASP.NET 4.5 in C# and VB if you’re interested. However, it’s listed here because you can create a project using the Web Forms template and still add in support for MVC.

Web API: This creates an application with both MVC and Web API support. The MVC support is included partly to display the API Help pages, which document the public API signature. You can read more about Web API in Chapter 11.

Single Page Application: The Single Page Application template sets you up for an application that’s primarily driven via JavaScript requests to Web API services rather than the traditional web page request / response cycle. The initial HTML is served via an MVC Home Controller, but the rest of the server-side interactions are handled by a Web API controller. This template uses the Knockout.js library to help manage interactions in the browser. Chapter 12 covers single-page applications, although the focus is on the Angular.js library rather than Knockout.js.

Facebook: This template makes it easier to build a Facebook “Canvas” application, a web application that appears hosted inside of the Facebook website. This template is beyond the scope of this book, but you can read more about it in this tutorial: http://go.microsoft .com/fwlink/?LinkId=301873.


Installing MVC 5 and Creating Applications

❘ 21

NOTE Changes to the Facebook API have caused authorization redirection

issues with this template at the time of this writing, as detailed in this CodePlex issue: https://aspnetwebstack.codeplex.com/workitem/1666. The fi x will likely require updating or replacing the Microsoft.AspNet.Mvc.Facebook NuGet package. Consult the bug reference above for status and fi x information.

Azure Mobile Service: If you have Visual Studio 2013 Update 2 (also known as 2013.2) installed, you’ll see this additional option. Because Azure Mobile Services now support Web API services, this template makes it easy to create a Web API intended for Azure Mobile Services. You can read more about it in this tutorial: http://msdn.microsoft.com/en-us/ library/windows/apps/xaml/dn629482.aspx.

Testing All the built-in project templates have an option to create a unit test project with sample unit tests.

RECOMMENDATION: CHECK THE BOX I hope you get in the habit of checking that Add Unit Tests box for every project you create. I’m not going to try to sell you the Unit Testing religion—not just yet. We talk about unit testing throughout the book, especially in Chapter 14, which covers unit testing and testable patterns, but we’re not going to try to ram it down your throat. Most developers I talk to are convinced that value exists in unit testing. Those who aren’t using unit tests would like to, but they’re worried that it’s just too hard. They don’t know where to get started, they’re worried that they’ll get it wrong, and they are just kind of paralyzed. I know just how they feel; I was there. So, here’s my sales pitch: Just check the box. You don’t have to know anything to do it; you don’t need an ALT.NET tattoo or a certification. We cover some unit testing in this book to get you started, but the best way to get started with unit testing is to just check the box, so that later you can start writing a few tests without having to set anything up.


22

CHAPTER 1 GETTING STARTED

Configuring Authentication You can choose the authentication method by clicking the Change Authentication button, which then opens the Change Authentication dialog, as shown in Figure 1-7.

FIGURE 1-7

There are four options: ➤

No Authentication: Used for an application that requires no authentication, such as a public website with no administration section.

Individual User Accounts: Used for applications that store user profiles locally, such as in a SQL Server database. This includes support for username / password accounts as well as social authentication providers.

Organizational Accounts: Used for accounts that authenticate via some form of Active Directory (including Azure Active Directory and Office 365).

Windows Authentication: Used for intranet applications.

This book most often uses Individual User Accounts. Chapter 7 offers a discussion of some of the additional options. You can click the Learn More link for each option in the Change Authentication dialog for the official documentation.

Configuring Windows Azure Resources Visual Studio 2013.2 adds an additional “Host in the cloud” option to configure Azure resources for your project right from the File ➪ New Project dialog. For more information about using this option, see this tutorial: http://azure.microsoft.com/en-us/documentation/articles/websites-dotnet-get-started/. For this chapter, we’ll run against the local development server, so ensure this checkbox is unchecked. Review your settings on the New ASP.NET MVC 5 Project dialog to make sure they match Figure 1-8, and then click OK. This creates a solution for you with two projects—one for the web application and one for the unit tests, as shown in Figure 1-9.


Installing MVC 5 and Creating Applications

FIGURE 1-8

FIGURE 1-9

â?&#x2DC; 23


24

CHAPTER 1 GETTING STARTED

New MVC projects include a Project_Readme.html fi le in the root of the application. This fi le is automatically displayed when your project is created, as shown in Figure 1-9. It is completely selfcontained—all styles are included via HTML style tags, so when you’re done with it you can just delete the one fi le. This Project_Readme.html fi le is customized for each application template and contains a lot of useful links to help you get started.

THE MVC APPLICATION STRUCTURE When you create a new ASP.NET MVC application with Visual Studio, it automatically adds several fi les and directories to the project, as shown in Figure 1-10. ASP.NET MVC projects created with the Internet application template have eight top-level directories, shown in Table 1-1.

FIGURE 1-10

TABLE 1-1: Default Top-Level Directories DIRECTORY

P URPOSE

/Controllers

Where you put Controller classes that handle URL requests

/Models

Where you put classes that represent and manipulate data and business objects

/Views

Where you put UI template files that are responsible for rendering output, such as HTML

/Scripts

Where you put JavaScript library files and scripts (.js)


The MVC Application Structure

DIRECTORY

P URPOSE

/fonts

The Bootstrap template system includes some custom web fonts, which are placed in this directory

/Content

Where you put CSS, images, and other site content, other than scripts

/App_Data

Where you store data files you want to read/write

/App_Start

Where you put configuration code for features like Routing, bundling, and Web API

WHAT IF I DON’T LIKE THAT DIRECTORY STRUCTURE? ASP.NET MVC does not require this structure. In fact, developers working on large applications will typically partition the application across multiple projects to make it more manageable (for example, data model classes often go in a separate class library project from the web application). The default project structure, however, does provide a nice default directory convention that you can use to keep your application concerns clean.

Note the following about these files and directories. When you expand: ➤

The /Controllers directory, you’ll find that Visual Studio added two Controller classes (see Figure 1-11)—HomeController and AccountController—by default to the project.

FIGURE 1-11

❘ 25


26

CHAPTER 1 GETTING STARTED

The /Views directory, you’ll find that three subdirectories—/Account, /Home, and / Shared—as well as several template files within them, were also added to the project by default (Figure 1-12).

FIGURE 1-12

The /Content and /Scripts directories, you’ll find the CSS files that is used to style all HTML on the site, as well as JavaScript libraries that can enable jQuery support within the application (see Figure 1-13).

The MvcMusicStore.Tests project, you’ll find a class that contains unit tests for your HomeController classes (see Figure 1-14).

These default fi les, added by Visual Studio, provide you with a basic structure for a working application, complete with homepage, about page, account login/logout/registration pages, and an unhandled error page (all wired up and working out of the box).


The MVC Application Structure

❘ 27

FIGURE 1-13

ASP.NET MVC and Conventions ASP.NET MVC applications, by default, rely heavily on conventions. This allows developers to avoid having to configure and specify things that can be inferred based on convention. For instance, MVC uses a convention-based directory-naming structure when resolving View templates, and this convention allows you to omit the location path when referencing views from within a Controller class. By default, ASP.NET MVC looks for the View template fi le within the \Views\ [ControllerName]\ directory underneath the application. MVC is designed around some sensible convention-based defaults that can be overridden as needed. This concept is commonly referred to as “convention over configuration.”


28

CHAPTER 1 GETTING STARTED

FIGURE 1-14

Convention over Configuration The convention over configuration concept was made popular by Ruby on Rails a few years back, and essentially means:

“We know, by now, how to build a web application. Let’s roll that experience into the framework so we don’t have to configure absolutely everything again.” You can see this concept at work in ASP.NET MVC by taking a look at the three core directories that make the application work: ➤

Controllers

Models

Views

You don’t have to set these folder names in the web.config fi le—they are just expected to be there by convention. This saves you the work of having to edit an XML file like your web.config, for example, in order to explicitly tell the MVC engine, “You can fi nd my views in the Views directory” — it already knows. It’s a convention.


Summary

❘ 29

This isn’t meant to be magical. Well, actually, it is; it’s just not meant to be black magic—the kind of magic where you may not get the outcome you expected (and moreover can actually harm you). ASP.NET MVC’s conventions are pretty straightforward. This is what is expected of your application’s structure: ➤

Each controller’s class name ends with Controller: ProductController, HomeController, and so on, and lives in the Controllers directory.

There is a single Views directory for all the views of your application.

Views that controllers use live in a subdirectory of the Views main directory and are named according to the controller name (minus the Controller suffix). For example, the views for the ProductController discussed earlier would live in /Views/Product.

All reusable UI elements live in a similar structure, but in a Shared directory in the Views folder. You’ll hear more about views in Chapter 3.

Conventions Simplify Communication You write code to communicate. You’re speaking to two very different audiences: ➤

You need to clearly and unambiguously communicate instructions to the computer for execution.

You want developers to be able to navigate and read your code for later maintenance, debugging, and enhancement.

We’ve already discussed how convention over configuration helps you to efficiently communicate your intent to MVC. Convention also helps you to clearly communicate with other developers (including your future self). Rather than having to describe every facet of how your applications are structured over and over, following common conventions allows MVC developers worldwide to share a common baseline for all our applications. One of the advantages of software design patterns in general is the way they establish a standard language. Because ASP.NET MVC applies the MVC pattern along with some opinionated conventions, MVC developers can very easily understand code—even in large applications—that they didn’t write (or don’t remember writing).

SUMMARY We’ve covered a lot of ground in this chapter. We began with an introduction to ASP.NET MVC, showing how the ASP.NET web framework and the MVC software pattern combine to provide a powerful system for building web applications. We looked at how ASP.NET MVC has matured through four previous releases, examining in more depth the features and focus of ASP.NET MVC 5. With the background established, you set up your development environment and began creating a sample MVC 5 application. You fi nished up by looking at the structure and components of an MVC 5 application. You’ll be looking at all those components in more detail in the following chapters, starting with controllers in Chapter 2.


30

â?&#x2DC;

CHAPTER 1 GETTING STARTED

REMINDER FOR ADVANCED READERS As mentioned in the introduction, the fi rst six chapters of this book are intended to provide a fi rm foundation in the fundamentals of ASP.NET MVC. If you already have a pretty good grasp of how ASP.NET MVC works, you might want to skip ahead to Chapter 7.


Contents

Introduction Chapter 1: Welcome to SQL Server Integration Services

SQL Server SSIS Historical Overview Whatâ&#x20AC;&#x2122;s New in SSIS Tools of the Trade Import and Export Wizard The SQL Server Data Tools Experience

SSIS Architecture

xxvii 1

2 2 3 3 4

5

Packages 5 Control Flow 5 Data Flow 9 Variables 14 Parameters 14 Error Handling and Logging 14

Editions of SQL Server 14 Summary 15 Chapter 2: The SSIS Tools

Import and Export Wizard SQL Server Data Tools The Solution Explorer Window

17

17 24 26

The SSIS Toolbox The Properties Windows

27 28

The SSIS Package Designer

28

Control Flow 29 Connection Managers 32 Variables 33 Data Flow 34 Parameters 35 Event Handlers 35 Package Explorer 36 Executing a Package 37

Management Studio 37 Summary 37

ftoc.indd 13

3/22/2014 10:38:49 AM


CONTENTS

Chapter 3: SSIS Tasks

SSIS Task Objects Using the Task Editor The Task Editor Expressions Tab

Looping and Sequence Tasks Script Task (.NET) Analysis Services Tasks Analysis Services Execute DDL Task Analysis Services Processing Task Data Mining Query Task

Data Flow Task Data Preparation Tasks Data Profiler File System Task Archiving a File FTP Task Getting a File Using FTP Web Service Task Retrieving Data Using the Web Service Task and XML Source Component XML Task Validating an XML File

RDBMS Server Tasks Bulk Insert Task Using the Bulk Insert Task Execute SQL Task

Workflow Tasks Execute Package Task Execute Process Task Message Queue Task Send Mail Task WMI Data Reader Task WMI Event Watcher Task Polling a Directory for the Delivery of a File

SMO Administration Tasks Transfer Database Task Transfer Error Messages Task Transfer Logins Task Transfer Master Stored Procedures Task Transfer Jobs Task Transfer SQL Server Objects Task

39

40 40 41

41 41 44 44 44 46

47 48 48 50 52 53 54 56 59 62 64

66 66 69 71

82 82 84 86 87 88 91 91

92 93 94 94 95 96 96

Summary 97 xiv

ftoc.indd 14

3/22/2014 10:38:49 AM


CONTENTS

Chapter 4: The Data Flow

99

Understanding the Data Flow 99 Data Viewers 100 Sources 101 OLE DB Source Excel Source Flat File Source Raw File Source XML Source ADO.NET Source

102 104 105 110 110 111

Destinations 111 Excel Destination Flat File Destination OLE DB Destination Raw File Destination Recordset Destination Data Mining Model Training DataReader Destination Dimension and Partition Processing

Common Transformations

112 112 112 113 114 114 114 114

115

Synchronous versus Asynchronous Transformations 115 Aggregate 115 Conditional Split 117 Data Conversion 118 Derived Column 119 Lookup 121 Row Count 121 Script Component 122 Slowly Changing Dimension 123 Sort 123 Union All 125

Other Transformations

126

Audit 126 Character Map 128 Copy Column 128 Data Mining Query 129 DQS Cleansing 130 Export Column 130 Fuzzy Lookup 132 Fuzzy Grouping 139 Import Column 143 Merge 145 xv

ftoc.indd 15

3/22/2014 10:38:49 AM


CONTENTS

Merge Join 146 Multicast 146 OLE DB Command 147 Percentage and Row Sampling 148 Pivot Transform 149 Unpivot 152 Term Extraction 154 Term Lookup 158

Data Flow Example 160 Summary 164 Chapter 5: U  sing Variables, Parameters, and Expressions

Dynamic Package Objects Variable Overview Parameter Overview Expression Overview

Understanding Data Types SSIS Data Types Date and Time Type Support How Wrong Data Types and Sizes Can Affect Performance Unicode and Non-Unicode Conversion Issues Casting in SSIS Expressions

Using Variables and Parameters Defining Variables Defining Parameters Variable and Parameter Data Types

Working with Expressions C#-Like? Close, but Not Completely The Expression Builder Syntax Basics Using Expressions in SSIS Packages

165

166 166 166 167

168 168 170 171 171 173

174 174 175 176

177 178 179 180 194

Summary 204 Chapter 6: Containers

205

Task Host Containers 205 Sequence Containers 206 Groups 207 For Loop Container 207 Foreach Loop Container 210

xvi

ftoc.indd 16

3/22/2014 10:38:49 AM


CONTENTS

Foreach File Enumerator Example Foreach ADO Enumerator Example

211 213

Summary 218 Chapter 7: Joining Data

The Lookup Transformation Using the Merge Join Transformation Contrasting SSIS and the Relational Join Lookup Features Building the Basic Package Using a Relational Join in the Source Using the Merge Join Transformation

Using the Lookup Transformation Full-Cache Mode No-Cache Mode Partial-Cache Mode Multiple Outputs Expressionable Properties Cascaded Lookup Operations

219

220 221 222 224 225 227 230

235 235 239 240 243 246 247

Cache Connection Manager and Cache Transform 249 Summary 252 Chapter 8: Creating an End-to-End Package

253

Basic Transformation Tutorial

253

Creating Connections Creating the Control Flow Creating the Data Flow Completing the Package Saving the Package Executing the Package

254 257 257 259 260 260

Typical Mainframe ETL with Data Scrubbing

261

Creating the Data Flow 263 Handling Dirty Data 263 Finalizing 268 Handling More Bad Data 269 Looping and the Dynamic Tasks 271 Looping 271 Making the Package Dynamic 272

Summary 274

xvii

ftoc.indd 17

3/22/2014 10:38:50 AM


CONTENTS

Chapter 9: Scripting in SSIS

Introducing SSIS Scripting Getting Started in SSIS Scripting Selecting the Scripting Language Using the VSTA Scripting IDE Example: Hello World Adding Code and Classes Using Managed Assemblies Example: Using Custom .NET Assemblies

Using the Script Task Configuring the Script Task Editor The Script Task Dts Object Accessing Variables in the Script Task Connecting to Data Sources in a Script Task Raising an Event in a Script Task Writing a Log Entry in a Script Task

Using the Script Component

275

276 277 277 278 279 281 282 283

286 287 288 289 293 303 309

310

Differences from a Script Task 310 Configuring the Script Component Editor 311 Accessing Variables in a Script Component 313 Connecting to Data Sources in a Script Component 314 Raising Events 314 Logging 315 Example: Data Validation 316 Synchronous versus Asynchronous 324

Essential Coding, Debugging, and Troubleshooting Techniques 327 Structured Exception Handling Script Debugging and Troubleshooting

327 330

Summary 333 Chapter 10: Advanced Data Cleansing in SSIS

Advanced Derived Column Use Text Parsing Example

Advanced Fuzzy Lookup and Fuzzy Grouping Fuzzy Lookup Fuzzy Grouping

DQS Cleansing Data Quality Services

335

336 338

340 340 347

350 351

xviii

ftoc.indd 18

3/22/2014 10:38:50 AM


CONTENTS

DQS Cleansing Transformation

Master Data Management Master Data Services

355

358 359

Summary 362 Chapter 11: Incremental Loads in SSIS

Control Table Pattern Querying the Control Table Querying the Source Table Updating the Control Table

SQL Server Change Data Capture Benefits of SQL Server CDC Preparing CDC Capture Instance Tables The CDC API Using the SSIS CDC Tools

363

363 364 366 366

367 368 369 371 372 374

Summary 379 Chapter 12: Loading a Data Warehouse

Data Profiling Initial Execution of the Data Profiling Task Reviewing the Results of the Data Profiling Task Turning Data Profile Results into Actionable ETL Steps

Data Extraction and Cleansing Dimension Table Loading Loading a Simple Dimension Table Loading a Complex Dimension Table Considerations and Alternatives to the SCD Transformation

381

383 383 386 390

391 391 392 397 408

Fact Table Loading 409 SSAS Processing 421 Using a Master ETL Package 426 Summary 428 Chapter 13: Using the Relational Engine

Data Extraction SELECT * Is Bad WHERE Is Your Friend Transform during Extract

429

430 430 432 433

xix

ftoc.indd 19

3/22/2014 10:38:50 AM


CONTENTS

Many ANDs Make Light Work 437 SORT in the Database 437 Modularize 439 SQL Server Does Text Files Too 440 Using Set-Based Logic 444

Data Loading Database Snapshots The MERGE Operator

446 446 448

Summary 452 Chapter 14: Accessing Heterogeneous Data

Excel and Access 64-Bit Support Working with Excel Files Working with Access

453

455 455 457 462

Importing from Oracle

469

Oracle Client Setup Importing Oracle Data

469 470

Using XML and Web Services Configuring the Web Service Task Working with XML Data as a Source

Flat Files Loading Flat Files Extracting Data from Flat Files

472 472 483

486 487 489

ODBC 491 Other Heterogeneous Sources 494 Summary 495 Chapter 15: Reliability and Scalability

Restarting Packages Simple Control Flow Containers within Containers and Checkpoints Variations on a Theme Inside the Checkpoint File

Package Transactions Single Package, Single Transaction Single Package, Multiple Transactions Two Packages, One Transaction Single Package Using a Native Transaction in SQL Server

497

498 499 501 503 505

507 508 509 511 512

xx

ftoc.indd 20

3/22/2014 10:38:50 AM


CONTENTS

Error Outputs Scaling Out Architectural Features Scaling Out Memory Pressures Scaling Out by Staging Data Scaling Out with Parallel Loading

513 516 516 517 517 522

Summary 528 Chapter 16: Understanding and Tuning the Data Flow Engine

The SSIS Engine Understanding the SSIS Data Flow and Control Flow Handling Workflows with the Control Flow Data Processing in the Data Flow Memory Buffer Architecture Types of Transformations Advanced Data Flow Execution Concepts

SSIS Data Flow Design and Tuning Data Flow Design Practices Optimizing Package Processing Troubleshooting Data Flow Performance Bottlenecks

529

530 530 533 533 534 534 543

549 550 555 558

Pipeline Performance Monitoring 559 Summary 562 Chapter 17: SSIS Software Development Life Cycle

Introduction to Software Development Life Cycles SDLCs: A Brief History Types of Software Development Life Cycles

Versioning and Source Code Control Subversion (SVN) Team Foundation Server, Team System, and SSIS

563

565 566 566

567 568 573

Summary 590 Chapter 18: Error and Event Handling

Using Precedence Constraints Precedence Constraint Basics Advanced Precedence Constraints and Expressions

Event Handling

591

592 592 593

601

Events 602

xxi

ftoc.indd 21

3/22/2014 10:38:50 AM


CONTENTS

Using Event Handlers Event Handler Inheritance

603 611

Breakpoints 612 Error Rows 616 Logging 622 Logging Providers Log Events Catalog Logging

622 623 627

Summary 629 Chapter 19: Programming and Extending SSIS

The Sample Components

631

632

Component 1: Source Adapter Component 2: Transform Component 3: Destination Adapter

632 633 634

The Pipeline Component Methods

634

Design-Time Functionality 635 Runtime 639 Connection Time 640

Building the Components

642

Preparation 642 Building the Source Component 648 Building the Transformation Component 660 Building the Destination Adapter 671

Using the Components Installing the Components Debugging Components Design Time Building the Complete Package Runtime Debugging

679 679 680 680 682 682

Upgrading to SQL Server 2014 687 Summary 687 Chapter 20: Adding a User Interface to Your Component

Three Key Steps for Designing the UI: An Overview Building the User Interface Adding the Project Implementing IDtsComponentUI Setting the UITypeName Building the Form

689

690 690 691 693 697 699

xxii

ftoc.indd 22

3/22/2014 10:38:50 AM


CONTENTS

Extending the User Interface

704

Runtime Connections Component Properties Handling Errors and Warnings Column Properties

704 707 708 711

Other UI Considerations 712 Summary 712 Chapter 21: External Management and WMI Task Implementation 715

External Management of SSIS with Managed Code

716

Setting Up a Test SSIS Package for Demonstration Purposes 716 The Managed Object Model Code Library 717 Catalog Management 718 Folder Management 719 Environments 720 The DTS Runtime Managed Code Library 722 SSIS Deployment Projects 722 Parameter Objects 723 Server Deployment 725 Executing SSIS Packages Deployed to the SSIS Catalog 726 Environment References 727

Package Operations Application Object Maintenance Operations Package Operations Package Monitoring Project, Folder, and Package Listing A Package Management Example

Package Log Providers Specifying Events to Log Programming to Log Providers SQL Server 2014 Operation Logs

Package Configurations Creating a Configuration Programming the Configuration Object Configuration Object

Windows Management Instrumentation Tasks WMI Reader Task Explained WMI Data Reader Example WMI Event Watcher Task WMI Event Watcher Task Example

728 729 729 732 734 735

745 747 748 749

751 752 753 754

755 755 756 762 763

Summary 766 xxiii

ftoc.indd 23

3/22/2014 10:38:50 AM


CONTENTS

Chapter 22: Administering SSIS

Using the SSIS Catalog

767

768

Setting the SSIS Catalog Properties 768 SSISDB 771

Deployment Models Project Deployment Model Package Deployment Model

Using T-SQL with SSIS Executing Packages Using Parameters Querying Tables for Parameter Values Using Environments Using Data Taps

Creating a Central SSIS Server Clustering SSIS Package Configuration Command-Line Utilities

772 773 775

781 781 782 783 784 789

790 792 794 798

DTExec 798 DTExecUI 799 DTUtil 804

Security 806 Securing the SSIS Catalog Legacy Security

806 809

Scheduling Packages

811

SQL Server Agent Proxy Accounts

811 813

64-Bit Issues Monitoring Package Executions Built-in Reporting Custom Reporting

814 815 815 819

Performance Counters 819 Summary 820 Appendix A: SSIS Crib Notes

When to Use Control Flow Tasks When to Use Data Flow Transforms Common Expressions and Scripts

821

821 822 824

xxiv

ftoc.indd 24

3/22/2014 10:38:50 AM


CONTENTS

Appendix B: SSIS Internal Views and Stored Procedures 829

Views 829 Stored Procedures 830 Appendix C: Interviewing for an ETL Developer Position 833

Questions833 Answers834 Index839

xxv

ftoc.indd 25

3/22/2014 10:38:50 AM


2

The SSIS Tools WHAT’S iN THiS CHAPTER? ➤➤

Working with the Import and Export Wizard

➤➤

Using the SQL Server Data Tools application

➤➤

Examining the windows used to create packages

➤➤

Utilizing Management Studio to administer your packages

As with any Microsoft product, SQL Server ships with a myriad of wizards and tools to make your life easier and reduce your time to market. In this chapter you will learn about some of the tools of the trade that are available to you and how to create your fi rst basic package. These wizards make transporting data and deploying your packages much easier and can save you hours of work in the long run, but they’re only a starting point in most cases. In the fi rst part of this chapter, you’ll look at the Import and Export Wizard, which enables you to create a package for importing or exporting data quickly with minimal transformations. As a matter of fact, you may run this tool in your day-to-day work without even knowing that SSIS is the back end for the wizard. The latter part of this chapter explores other, more powerful, tools that are available to you, such as SQL Server Data Tools (SSDT). By the time this chapter is complete, you will have created your fi rst SSIS package.

iMPoRT AND ExPoRT WiZARD The Import and Export Wizard is the easiest method to move data from sources like Oracle, DB2, SQL Server, Excel, and text fi les to nearly any destination, and it is available across all versions of SQL Server — even those that don’t include SSIS. This wizard uses SSIS as a framework and can optionally save a package as its output prior to executing. The package it produces may not be the most elegant, but it can eliminate a lot of tedious package

c02.indd 17

3/22/2014 8:01:35 AM


18 

❘  CHAPTER 2  The SSIS Tools

development work and it provides the building blocks that are necessary for building the remainder of the package. Oftentimes as an SSIS developer, you’ll want to relegate the grunt work and heavy lifting to the wizard when you want to just move data for a onetime load, and then do the more complex coding yourself. As with any of the SSIS tools, there are numerous ways to open the tool. To open the Import and Export Wizard, right-click the database you want to import data from or export data to in SQL Server Management Studio and select Tasks ➪ Import Data (or Export Data based on what task you’re performing). You can also open the wizard by right-clicking the SSIS Packages folder in SSDT and selecting SSIS Import and Export Wizard. Another common way to open it is from the Start menu under SQL Server 2014, where it’s called Import and Export Data. The last way to open the wizard is by typing dtswizard.exe at the command line or Run prompt. Regardless of whether you need to import or export data, the first few screens in the wizard look very similar. When the wizard appears, you’ll see the typical Microsoft wizard welcome screen. Click Next to begin specifying the source connection. If you had opened the wizard from Management Studio by selecting Export Data, this screen is pre-populated. In this screen you specify where your data is coming from in the Source dropdown box. Once you select the source, the rest of the options on the dialog may vary based on the type of connection. The default source is .Net Framework Data Provider for Odbc. Out of the box, you have ODBC and OLE DB sources that connect to SQL Server, Oracle, and Access. You can also use text files, Excel files, and XML files. Traditionally, the SQL Native Client is the provider used in SSIS because it gives additional functionality during design time. Change the data source to use the SQL Server Native Client 11.0 provider. For SQL Server, you must enter the server name, as well as the user name and password you’d like to use. If you’re going to connect with your Windows account, simply select Use Windows Authentication. Windows Authentication will pass your Windows local or domain credentials into the data source. Lastly, choose a database to which you want to connect. For most of the examples in this book, you’ll use the AdventureWorksDW database or a variation of that DW database, shown in Figure 2-1. This database can be downloaded at www.wrox.com. Note   Additional sources such as Sybase and DB2 are also available if you install the vendor’s OLE DB providers. You can download the OLE DB provider for DB2 free if you’re using Enterprise Edition by going to the SQL Server Feature Pack on the Microsoft website. (As of this writing, the SQL Server 2014 Feature Pack has not be released. However, the SQL 2012 Feature Pack will work for 2014 as well.)

Note   In 2011, Microsoft released information regarding the appropriate provider types to use for new development. It was recommended that any new development should be done with ODBC providers rather than OLE DB. This rule should only be followed for home grown applications for now. SSIS developers should continue using OLE DB because ODBC does not have full feature parity yet to complete some ordinary tasks.

c02.indd 18

3/22/2014 8:01:35 AM


Import and Export Wizard 

❘  19

Figure 2-1

After you click Next, you are taken to the next screen in the wizard, where you specify the destination for your data. The properties for this screen are identical to those for the previous screen with the exception of the database. Change the Destination provider to SQL Server Native Client 11.0, then select TempDB from the Database dropdown. This will create and load the tables into a temporary space, which will disappear once you restart your instance of SQL Server. Click Next again to be taken to the Specify Table Copy or Query screen (see Figure 2-2). Here, if you select “Copy data from one or more tables or views,” you can simply check the tables you want. If you select “Write a query to specify the data to transfer,” you can write an ad hoc query (after clicking Next) that defines where to select the data from, or what stored procedure to use to retrieve your data. For the purpose of this example, select “Copy data from one or more tables or views” and click Next. This takes you to the Select Source Tables and Views screen, where you can check the tables or views that you want to transfer to the destination (see Figure 2-3). For this tutorial, check a couple of tables such as FactResellerSales and FactInternetSales in the AdventureWorksDW database.

c02.indd 19

3/22/2014 8:01:35 AM


20 

❘  CHAPTER 2  The SSIS Tools

Figure 2-2

Figure 2-3

c02.indd 20

3/22/2014 8:01:35 AM


Import and Export Wizard 

❘  21

If you wish, you can click the Edit buttons to access the Column Mappings dialog for each table (see Figure 2-4). Here you can change the mapping between each source and destination column. For example, if you want the ProductKey column to go to the ProductKey2 column on the destination, simply select the Destination cell for the ProductKey column and point it to the new column, or select <ignore> to ignore the column altogether.

Figure 2-4

Note that because you’re moving the data to a new database that doesn’t already contain the FactInternetSales table, the “Create destination table” option is one of the few options enabled by default. This will create the table on the destination before populating it with data from the source. If the table already existed, the data will append existing records but you could specify that all rows in the destination table should be deleted before populating it. Finally, you can check the “Enable identity insert” option if the table into which you are moving data has an identity column. If the table does have an identity column, the wizard automatically enables this option. If you don’t have the option enabled and you try to move data into an identity column, the wizard will fail to execute. For the purpose of this example, don’t change any of the settings in this screen. Click OK to apply the settings from the Column Mappings dialog and then click Next to proceed. If no errors are found, you are taken to the Save and Run Package screen (Figure 2-5). Here you can specify whether you want the package to execute only once, or whether you’d like to save the package for later use. As shown earlier, it isn’t necessary to execute the package here. You can uncheck Run Immediately and just save the package for later modification and execution.

c02.indd 21

3/22/2014 8:01:35 AM


22 

❘  CHAPTER 2  The SSIS Tools

For this example, check the options for Run Immediately, Save SSIS Package, and File System. This collection of options will execute the package and save it as a .dtsx file to your computer. You learn more about where to save your SSIS packages later in this chapter. Note that if you save the package to SQL Server or to the file system, you’re saving the package with the Package Deployment Model. We’ll discuss more about the package deployment model in Chapter 22.

Figure 2-5

In this screen, you’re also asked how you wish to protect the sensitive data in your package. SSIS packages are essentially large XML files behind the scenes, and encryption of sensitive data, such as passwords, is critical to ensuring that no one sees that information by opening the XML manually. Again, you learn more about this later in this chapter, so for now just change the Package Protection Level property to “Encrypt sensitive data with password” to protect your sensitive data with a password, and give the dialog a password (as shown in Figure 2-5). You are then taken to the Save SSIS Package screen, where you can type the name of the package and the location to which you want to save it (see Figure 2-6).

c02.indd 22

3/22/2014 8:01:35 AM


Import and Export Wizard 

❘  23

Figure 2-6

Click Next and confirm what tasks you wish the wizard to perform. The package will then execute when you click Finish, and you’ll see the page shown in Figure 2-7. Any errors are displayed in the Message column. You can also see how many rows were copied over in this column, and you can double-click an entry that failed to see why, in the event that there are errors during execution.

Figure 2-7

c02.indd 23

3/22/2014 8:01:36 AM


24 

❘  CHAPTER 2  The SSIS Tools

After the wizard executes, the package can be found in the location that you have specified, but the default is the My Documents directory. You can open the package that executed in SSDT by creating a project in SSDT and copying and pasting the package into the project or by right-clicking on Packages and selecting Add Existing Package.

SQL Server Data Tools The SQL Server Data Tools (SSDT) is where you’ll spend most of your time as an SSIS developer. It is where you create and deploy your SSIS projects. SSDT uses a subset of the full version of Visual Studio 2013. If you have the full version of Visual Studio 2013 and SQL Server 2014 installed, you can create business intelligence projects there as well as in the full interface, but as far as SSIS is concerned, there’s no added value in using the full version of Visual Studio. Either way, the user experience is the same. In SQL Server 2014, the SSIS development environment is detached from SQL Server, so you can develop your SSIS solution offline and then deploy it wherever you like in a single click. In prior versions of Integration Services, SSDT was part of the SQL Server installation, but with the release of SQL Server 2014, SSDT has been decoupled from SQL Server installer. This means to develop new SSIS packages you must go download SSDT from the Microsoft download site. The benefit of this change is that developers will now see more frequent enhancements to the development environment. Use a search engine with the term “SQL Server Data Tools for Visual Studio 2013” to find the most recent release. After you download and install SSDT you’ll find SSDT in the root of the Microsoft SQL Server 2014 program group from the Start menu. Once you start SSDT, you are taken to the Start Page, an example of which is shown in Figure 2-8, before you open or create your first project. You can open more windows (you learn about these various windows in a moment) by clicking their corresponding icon in the upper-right corner of SSDT or under the View menu. Please note that some of the screenshots in this book, such as Figures 2-8, 2-9, and 2-10, were shot using Visual Studio 2012, which also works with SQL Server 2014. You may also choose to use Visual Studio 2013 if you prefer, and the screenshot may be slightly different. The Start Page contains key information about your SSDT environment, such as the last few projects that you had open (under the Recent Projects section). You can also see the latest MSDN news under the Get Started section from the Latest News box. By clicking the Latest News box, you can also set the RSS feed that you’re consuming as well. The Visual Studio environment is that it gives you full access to the Visual Studio feature set, such as debugging, automatic integration with source code control systems, and integrated help. It is a familiar environment for developers and makes deployments easy. The starting point for SSIS is to create a solution and project.

c02.indd 24

➤➤

A solution is a container in Visual Studio that holds one or many projects.

➤➤

A project in SSIS is a container of one or many packages and related files. You can also create projects for Analysis Services, Reporting Services, C#, and so on. All of these projects can be bundled together with a single solution, so a C# developer is in the same environment as an SSIS developer. Make sure you put packages that belong together into a single project since the project is the unit of deployment in SQL Server 2014.

3/22/2014 8:01:36 AM


SQL Server Data Tools 

❘  25

Figure 2-8

To start a new SSIS project, you first need to open SSDT and select File ➪ New ➪ Project. Note a series of new templates (shown in Figure 2-9) in your template list now that you’ve installed SSDT for Visual Studio 2013. From the Installed Templates pane on the left, select Integration Services and then select Integration Services Project. Name your project and solution whatever you like (I named the solution ProSSISSolution and the project ProSSISProject). Also shown in Figure 2-9 is another type of SSIS project called the Integration Services Import Project Wizard, which is used to bring packages into a project from another deployed project. Click OK at this point to create the solution, the project, and your first package. Typically, you want to align your projects into solutions that fit the business requirement that you’re trying to meet. For example, you may be assigned to a business project for the creation of a data warehouse. That warehouse project would probably have ETL, an SSAS cube, and Reporting Services reports. You could place all of these into a single solution so you could manage them from a unified interface. Note that once you begin work in Visual Studio, if your solution contains only a single project, the solution will be hidden by default. If you want to always see the solution name, go to Tools ➪ Options and check Always Show Solution from the Projects and Solutions group (shown in Figure 2-10). If you’re doing any type of source control, this option should always be turned on so you can check in the solution easily. Otherwise, once a second project is added to the solution, you’ll see the solution and both projects under the solution.

c02.indd 25

3/22/2014 8:01:36 AM


26 

❘  CHAPTER 2  The SSIS Tools

Figure 2-9

Figure 2-10

The Solution Explorer Window The Solution Explorer window is where you can find all your created SSIS packages, project connection managers, project parameters, and any other miscellaneous files needed for the project, such as installation documents. As mentioned earlier, a solution is a container that holds a series of projects. Each project holds a myriad of objects for whatever type of project you’re working on.

c02.indd 26

3/22/2014 8:01:36 AM


The Solution Explorer Window 

❘  27

Once you create a solution, you can store many projects inside of it. For example, you may have a solution that has your VB.NET application and all the SSIS packages that support that application. In this case, you would have two projects: one for VB and another for SSIS contained within the single solution. After creating a new project, your Solution Explorer window will contain a series of empty folders. Figure 2-11 shows a partially filled Solution Explorer. In this screenshot, there’s a solution named ProSSISSolution with two projects: SSASProject and ProSSISProject. Inside that project are two SSIS packages. To create a new project inside an existing open solution, right-click the solution name in the Solution Explorer window and select Add ➪ New Project. To add a new item to your project in the folder, right-click the folder that holds the type of item that you wish to add and select New Connection Manager or New SSIS Package. You can also drag or copy and paste files into the project if they are of a similar type, like .dtsx files.

Figure 2-11

If you look in the directory that contains your solution and project files, you’ll see all the files that are represented in the Solution Explorer window. Some of the base files you may see will have the following extensions: ➤➤

.dtsx: An SSIS package, which uses its legacy extension from the early beta cycles of SQL

Server 2005 when SSIS was still called DTS ➤➤

.conmgr: A connection manager that can be shared across any package in the entire project

➤➤

.sln: A solution file that contains one or more projects

➤➤

.dtproj: An SSIS project file

➤➤

.params: An SSIS project parameter file

If you copy any file that does not match the .params, .conmgr, or .dtsx extension, it will be placed in the Miscellaneous folder. This folder is used to hold any files that describe the installation of the package, such as Word documents or requirements documents. You can put anything you like in that folder, and it can potentially all be checked into a source control system like Team Foundation Server (TFS) or SourceSafe with the code. You’ll learn more about source control systems in Chapter 17.

The SSIS Toolbox The SSIS Toolbox contains all the items that you can use in the particular tab’s design pane at any given point in time. For example, the Control Flow tab has a list of tasks (a partial list is shown in Figure 2-12). This list may grow depending on what custom tasks are installed, and the list will be completely different when you’re in a different tab, such as the Data Flow tab. All the tasks shown in Figure 2-12 are covered in Chapter 3 in much more detail.

c02.indd 27

3/22/2014 8:01:36 AM


28 

❘  CHAPTER 2  The SSIS Tools

In the Control Flow tab, the Toolbox is organized into tabs such as Favorites, Common, Containers, and Other Tasks. These tabs can be collapsed and expanded for usability. As you use the Toolbox, you may want to customize your view by removing tasks or tabs from the default view. You can move or customize the list of items in your Toolbox by right-clicking on a given component (refer to Figure 2-12). You can also reset the entire Toolbox to its defaults by right-clicking and selecting Restore Toolbox Defaults. As you install third-party components, those tasks will now automatically appear in the Toolbox after you refresh the Toolbox or when you reopen SSDT.

The Properties Windows You can use the Properties window (shown in Figure 2-13) to customize any item that you have selected in the Control Flow or Data Flow tabs. For example, if you select a task in the design pane of those tabs, you’ll be shown a list of properties to configure, such as the task’s name and what query it’s going to use. The view varies widely based on what item you have selected. Figure 2-13 shows the properties of the Execute Process task you created earlier in this chapter. Most tasks can be configured through the user interface of the tasks Figure 2-12 or by going to the Properties pane when the task is selected. Note that the Properties pane may contain some advanced properties not shown in the user interface for the component. To edit the properties for the package, simply select the design pane in the background. If the Properties pane is closed, you can press F4 to reopen it or select the Properties Window button under View.

The SSIS Package Designer The SSIS Package Designer contains the design panes that you use to create an SSIS package. This tool contains all the items you need to move data or create a workflow with minimal or no code. The great thing about Figure 2-13 SSIS is that it is like programming with building blocks. The Package Designer contains five tabs: Control Flow, Data Flow, Parameters, Event Handlers, and Package Explorer. One additional tab, Progress, also appears when you execute packages. This Progress tab is renamed to Execution Results after the package stops running and you click Stop. This chapter focuses on exploring the Control Flow tab, and the bulk of the next chapter dives into details about this tab. In SSIS, the Control Flow contains tasks and the workflow of the package and is separated from most of the movement of data in the Data Flow tab. This usability feature gives you greater control when creating and editing packages. The task that binds the Control Flow and Data Flow together is the Data Flow Task, which you study in depth over the next two chapters.

c02.indd 28

3/22/2014 8:01:36 AM


The SSIS Package Designer 

❘  29

Understanding the difference between the Control Flow and Data Flow tabs represents one of the largest learning curves for a new SSIS developer. The easiest way to keep them straight is to think of the Data Flow tab as simply a way to configure the Data Flow Task. This separation gives you a huge amount of power when configuring the task. The other way to differentiate the two tabs is that the Control Flow tab handles the workflow of the package and ties the tasks together, whereas the Data Flow tab handles a data load.

Control Flow The Control Flow contains the workflow parts of the package, which include the tasks, containers, and precedence constraints. SSIS has introduced the new concept of containers, which was briefly discussed in Chapter 1 and is covered in detail in Chapter 6. In the Control Flow tab, you can click and drag a task from the SSIS Toolbox into the Control Flow design pane. Once you have a task created, you can double-click the task to configure it. Until the task is configured, you may see a yellow warning or red error indicator on the task. After you configure the task, you can link it to other tasks by using precedence constraints. Once you click the task, you’ll notice a green arrow pointing down from it, as shown in Figure 2-14.

Figure 2-14

For example, to create an On Success precedence constraint, click the green arrow coming out of the task and drag it to the task you wish to link to the first task. In Figure 2-15, you can see the On Success precedence constraint between an Execute Process task called EPR - Run Notepad and an Execute Process task called EPR - Run Calc. In the Data Flow tab, when you click a source or a transformation, you’ll also see a blue and red arrow pointing down, enabling you to quickly direct your good (blue) or bad (red) data to a separate output. Therefore, if you run a formula that returns an error in the Data Flow, that single row could be outputted to a different table, and then all other rows could continue down the proper path.

Figure 2-15

In the Control Flow, though, you need to use a different approach. If you want the next task to execute only if the first task has failed, create a precedence constraint as shown earlier for the On Success constraint. After the constraint is created, double-click the constraint arrow. You’ll be taken to the Precedence Constraint Editor (see Figure 2-16). Use this editor to set what type of constraint you’ll be using. Three options are available in the Value dropdown field: Success, Failure, or Completion. A success constraint will fire the second task or container only when the first task or container succeeds. A failure constraint executes the second task or container only when the first task fails. The last scenario is a completion constraint, which will execute the second task or container whether the first task succeeds or fails. In SSIS, you have the option to add a logical AND or OR when a task has multiple constraints. In the Precedence Constraint Editor in SSIS, you can configure the task to execute only if the group of predecessor tasks has completed (AND), or if any one of the predecessor tasks has completed (OR).

c02.indd 29

3/22/2014 8:01:36 AM


30 

❘  CHAPTER 2  The SSIS Tools

Figure 2-16

If a constraint is a logical AND, the precedence constraint line is solid. If it is set to OR, the line is dotted. This is useful if you want to be notified when any one of the tasks fails by using the logical OR constraint. In the Evaluation Operation dropdown, you can edit how the task will be evaluated: ➤➤

Constraint: Evaluates the success, failure, or completion of the predecessor task or tasks

➤➤

Expression: Evaluates the success of a customized condition that is programmed using an expression

➤➤

Expression and Constraint: Evaluates both the expression and the constraint before moving to the next task

➤➤

Expression or Constraint: Determines whether either the expression or the constraint has been successfully met before moving to the next task

If you select Expression or one of its variants as your option, you’ll be able to type an expression in the Expression box. An expression is usually used to evaluate a variable before proceeding to the next task. For example, if you want to ensure that InputFileVariable variable is equal to the Variable2 variable, you would use the following syntax in the Expression box: @InputFileVariable == @Variable2

You can also single-click the constraint and use the Properties window on the right to set these properties, if you prefer not to use the editor. Now that you know more about constraints, it’s a good time to look at a scenario and how the constraints apply to your environment. The example shown in Figure 2-17 demonstrates how flexible precedence constraints can be. The first Script Task runs a script to determine whether the

c02.indd 30

3/22/2014 8:01:36 AM


The SSIS Package Designer 

❘  31

file exists. An expression on the precedence constraint coming out of the Script Task determines whether the answer returned from the script is set to true or false. If the file exists, then Task A is run; otherwise, Task B is run. After that, note that regardless of whether Task A or B is run, the Archive Script Task always runs because of the Logical Or constraint. Finally, if the Sequence Container succeeds, then Task C is run, and if it does not, then the Alert Script Task is run. You may have noticed that in Figure 2-17, I added the names of the precedence constraints (success, failure, completion) to each of the arrows. This may be necessary for those who are colorblind (and is required for this book because it’s printed in black and white). To do this in SSDT, select Tools ➪ Options, and then check “Show precedence constraint labels” under the Business Intelligence Designers ➪ Integration Services Designers tab, as shown in Figure 2-18. Figure 2-17

Figure 2-18

Task Grouping A very nice usability feature in SSIS is the capability to group tasks or transforms logically in containers. For example, if you have a group of tasks that create and purge the staging environment, you can group them together so that your package is not cluttered visually. For example, in Figure 2-19 there are two tasks to load data and send a message. To group them, select both tasks by clicking one task and holding the Ctrl key down while you select the second task. Then, right-click the tasks and select Group. Figure 2-19

c02.indd 31

3/22/2014 8:01:37 AM


32 

❘  CHAPTER 2  The SSIS Tools

Note   Groups and containers are not the same. Groups are a usability feature to bring together components. Containers on the other hand allow you to pass properties into them. You can read more about groups, containers, and their differences in Chapter 6.

After you have the two tasks grouped, you’ll see a box container around them. A group is not the same as a container. It only gives you a usability feature to bring tasks together. They don’t share properties like transactions. To rename the group, simply double-click the container and type the new name over the old one. You can also collapse the group so that your package isn’t cluttered. To do this, just click the arrows that are pointing downward in the group. Once collapsed, your grouping will look like Figure 2-20. You Figure 2-20 can also ungroup the tasks by right-clicking the group and selecting Ungroup. This same type of group can be created in the Data Flow tab to logically group sources, transformations, and destinations together. You’ll learn more about containers in Chapter 6.

Annotation Annotations are a key part of any package, and a good developer won’t fail to include them. An annotation is a comment that you place in your package to help others and yourself understand what is happening in the package. To add an annotation, right-click where you want to place the comment, select Add Annotation, and begin typing. You can resize the box if you need more room. It is a good idea to always add an annotation to your package that shows the title and version of your package. Most SSIS developers also add a version history annotation note to the package, so that they can see what has changed in the package between releases and who performed the change. You can see an example of this in Figure 2-21.

Figure 2-21

Connection Managers You may have already noticed the Connection Managers tab at the bottom of your Package Designer pane. This tab contains a list of connections that both Control Flow and Data Flow Tasks can use. Whether the connection is an FTP address or a connection to an Analysis Services server, you’ll see a reference to it here. These connections can be referenced as either sources or targets in any of the operations, and they can connect to relational or Analysis Services databases, flat files, or other data sources. They’re also used in many of the SSIS tasks.

c02.indd 32

3/22/2014 8:01:37 AM


The SSIS Package Designer 

❘  33

When you create a new package, no connections are defined. You can create a connection by rightclicking in the Connections area and choosing the appropriate data connection type. Once the connection is created, you can rename it to fit your naming conventions or to better describe what is contained in the connection. Nearly any task or transformation that uses data or references a file will require a Connection Manager. Figure 2-22 shows a few connections: two to relational databases (AdventureWorksDW and Stage), an SMTP reference, and a directory.

Figure 2-22

Notice the two Connection Managers that refer to the AdventureWorksDW database and the staging database. The one with a database icon is a local Connection Manager that can be seen only inside the current package. The Connection Manager with (project) in front is a project connection that can be seen in any package. Any local Connection Manager can be converted to a project connection by right-clicking it and selecting Convert to Project Connection. Note that we have used a naming convention so the designer can easily recognize what type of connection it is.

Variables Variables are a powerful piece of the SSIS architecture; they enable you to dynamically control the package at runtime, much like you do in any .NET language. There are two types of variables: system and user. System variables are those built into SSIS, such as a package name or the package’s start time; user variables are created by the SSIS developer. Variables can also have varying scope, with the default scope being the entire package. They can also be set to be in the scope of a container, a task, or an event handler inside the package. One of the optional design-time windows can display a list of variables. To access the Variables window, right-click in the design pane and select Variables, or select Variables from the SSIS menu. The Variables window (shown in Figure 2-23) will appear in the bottom of SSDT by default. Also by default, you will see only the user variables; to see the system variables as well, click Grid Options and then select the Show System Variables icon in the top of the window. To add a new variable, click the Add Variable icon in the Variables window and type the variable name.

Figure 2-23

c02.indd 33

3/22/2014 8:01:37 AM


34 

❘  CHAPTER 2  The SSIS Tools

When you click the Add Variable icon, whatever task or container you select at the time will be the scope for the variable. Once the scope was set for a variable in the past SQL Server 2005 and 2008 releases, it could not be changed. Now a nice little feature in 2014 is you can change the variable scope at any time. Some of the additional columns are the Namespace and Raise Event on Variable Change properties. Lastly, you can select a variable and go to the Properties pane to see extended properties on the variable. We discuss these properties in more depth in Chapter 3. You’ll find yourself regularly using system variables throughout your package for auditing or error handling. Some of the package-scoped system variables that you may find interesting for auditing purposes are listed in the following table. Variable Name

Data T ype

Description

CreationDate

DateTime

Date when the package was created

InteractiveMode

Boolean

Indicates how the package was executed. If the package was executed from SSDT, this would be set to true. If it was executed from a SQL Server Agent job, it would be set to false.

MachineName

String

Computer on which the package is running

PackageID

String

Globally unique identifier (GUID) for the package

PackageName

String

Name of the package

StartTime

DateTime

Time when the package started

UserName

String

User who started the package

VersionBuild

Int32

Version of the package

Variables are discussed in greater detail in each chapter. For a full list of system variables, please refer to Books Online under “System Variables.”

Data Flow Most of your time in SSIS is spent in the Data Flow tab. When you add a Data Flow Task to the Control Flow design surface, a subsequent Data Flow is created in the Data Flow tab. Whereas a package has a single Control Flow, it can have many Data Flows. You can expand the Data Flow by double-clicking the task or by going to the Data Flow tab and selecting the appropriate Data Flow Task from the top dropdown box (shown in Figure 2-24). In the Data Flow, the key components are sources, destinations transformations (which appear in the SSIS Toolbox), and paths. Unlike in the Control Flow, where tasks and containers are connected by precedence constraints that define the package’s execution workflow; in the Data Flow, sources, transformations, and destinations are connected by paths that define the flow of data between these components. As you make a connection, the metadata (information about the columns and their data types) becomes available to the next component in the Data Flow path. Everything after the source is performed in memory with a very few exceptions.

c02.indd 34

3/22/2014 8:01:37 AM


The SSIS Package Designer 

❘  35

Figure 2-24

When you first start defining the Data Flow, you add a source component to connect to a data source, and then a destination to go to. The transformations (also known as transforms throughout this book) modify the data before it is written to the destination. As the data flows through the path from transform to transform, the data changes based on what transform you have selected. This entire process is covered in much more detail in Chapter 4.

Parameters The Parameters tab enables you to create input parameters for a package. These are different from variables in that they can easily be passed in from a DBA or a job. If you’re familiar with SQL Server 2005 or 2008 SSIS, these best resemble configuration files and are indeed replacements for configuration files and tables. You can find parameters in the list of tabs in SSIS. This tab identifies project level parameters but you can also have parameters that are specific to individual packages. Parameters can be made secure by setting the Sensitive property to True, as shown in Figure 2-25, and they can be used to override nearly any property in SSIS. Some parameters can also be set to Required by setting the corresponding property to True, meaning the package won’t run without passing in this parameter. Using parameters will be discussed in more detail in Chapter 5.

Figure 2-25

Event Handlers The Event Handlers tab enables you to create workflows to handle errors, warnings, or completion in tasks, containers, or packages. For example, if you want to trap any errors and have them e-mailed to you, you could create an OnError event handler that is scoped to the entire package and configure it to send a message out to an operator.

c02.indd 35

3/22/2014 8:01:37 AM


36 

❘  CHAPTER 2  The SSIS Tools

You can configure the event handler’s scope under the Executable dropdown box. An executable can be a package, a Foreach Loop container, a For Loop container, a Sequence container, or a task. In the Event Handler box, you can specify the event you wish to monitor. The events you can select are described in the following table: Event

When Event Is R aised

OnError

When an error occurs

OnExecStatusChanged

When an executable’s status changes

OnInformation

When an informational event is raised during the validation and execution of an executable

OnPostExecute

When an executable completes

OnPostValidate

When an executable’s validation is complete

OnPreExecute

Before an executable runs

OnPreValidate

Before an executable’s validation begins

OnProgress

When measurable progress has happened on an executable

OnQueryCancel

When a query has been instructed to cancel

OnTaskFailed

When a task fails

OnVariableValueChanged

When a variable is changed at runtime

OnWarning

When a warning occurs in your package

Event handlers are critically important to developing a package that is “self-healing” — that is, it can correct its own problems. The key events to handle are OnError, OnWarning, OnPreExecute, and OnPostExecute. You will learn more about event handlers in Chapter 18.

Package Explorer The final tab in the SSIS Package Designer is the Package Explorer tab, shown in Figure 2-26. This tab consolidates all the design panes into a single view, and lists all the tasks, connections, containers, event handlers, variables, and transforms in your package. You can double-click any item here to configure it easily. You can also modify the properties for the item in the Properties window on the right after selecting the item you wish to modify. This tab is useful if you have a task that is throwing an error and you can’t find it Figure 2-26 to remove or fix it. This problem happens sometimes when you have tasks that accidentally fall behind a container or another task.

c02.indd 36

3/22/2014 8:01:38 AM


Summary 

❘  37

Executing a Package When you want to execute a package, you can click the Play icon on the toolbar, or press F5, or choose Debug ➪ Start. You can also execute packages by right-clicking the package in Solution Explorer and selecting Execute Package. This last technique may be a better habit to get into because clicking the Play button initiates a build, and if your packages are in a solution that has multiple projects, it may also deploy SSRS reports or SSAS cubes if those projects are included in the solution. This puts the design environment into execution mode, opens several new windows, enables several new menu and toolbar items, and begins to execute the package. When the package finishes running, SSDT doesn’t immediately go back to design mode but rather stays in execution mode to allow you to inspect any runtime variables or view any execution output. This also means that you can’t make some changes to the objects within the package. You may already be familiar with this concept from executing .NET projects. To return to design mode, you must click the Stop icon on the debugging toolbar, or press Shift+F5, or choose Debug ➪ Stop Debugging.

Management Studio SSIS delineates between the SSIS developer and the administrator. SQL Server Management Studio is where administrators do most of their work — executing, securing, and updating packages. From the Management Studio interface, the administrator is not able to design packages, however. This function is reserved for SSDT only. You can open SQL Server Management Studio under the Microsoft SQL Server program group on the Start menu. Then, in the Object Browser pane (which can be opened from the View menu if it’s closed), select Connect ➪ Database Engine. Type your SQL Server instance name and click Connect. If you receive an error, you may want to jump ahead to Chapter 22, which explains how to correct connectivity issues. There’s also an SSIS service you can connect to, but this is for packages running in legacy mode. You’ll learn much more about this in Chapter 22 as well.

Summary This chapter provided an overview of the main SSIS wizards and core tools. The Import and Export Wizard is a quick way to create a package that does a simple import or export of data. The wizard is capable of producing a package that can be run multiple times. You were then taken on a tour of the SQL Server Data Tools (SSDT), which is where you’ll be spending most of your time as you develop packages. You looked at the key parts of the interface. Don’t worry if you don’t yet understand all the components of SSIS. Now that you have been exposed to the basic concepts, you’ll dive deeper into SSIS as you look at each component. Now that you’ve gotten your feet wet, it’s time to explore the real power of SSIS, which lies in the multitude of tasks you can use in your packages. You will learn about some of the more common ones in Chapter 3, and containers are covered in depth in Chapter 6.

c02.indd 37

3/22/2014 8:01:38 AM


c02.indd 38

3/22/2014 8:01:38 AM

Wiley Programming Sampler  

Sample chapters from Wiley's popular Programming titles.

Wiley Programming Sampler  

Sample chapters from Wiley's popular Programming titles.

Advertisement