Through the authors' carefully constructed explanations and examples, you will develop an understanding of Swift grammar and the elements of effective Swift. See the Glog! Download Ebook Swift Programming: The Big Nerd Ranch Guide ( 2nd Edition) (Big Nerd Ranch Guides) PDF: text, images, music, video. As an aspiring iOS developer, you face three major tasks: You must learn the Swift language. Swift is the recommended development language.
|Language:||English, Spanish, Indonesian|
|Genre:||Business & Career|
|ePub File Size:||28.77 MB|
|PDF File Size:||17.58 MB|
|Distribution:||Free* [*Regsitration Required]|
teach Swift. Big Nerd Ranch provided us with the time and space to work on this project. We hope that this book lives up to the trust and the support that we have. Apple's Worldwide Developers Conference is an annual landmark event for its developer community. It is a big deal every year, but was particularly special. Swift Programming: The Big Nerd Ranch Guide (Big Nerd Ranch Guides) pdf download, Swift Programming: The Big Nerd Ranch Guide (Big.
For example, imagine checking an age constant of type Int looking for a specific demographic: But they are not the hexadecimal Unicode numbers. Other additions include new chapters on debugging and accessibility and improved coverage of Core Data. Hit Command-Z to undo. The answer is canonical equivalence.
Submit Search. Successfully reported this slideshow. We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime. Download [Pdf] Swift Programming: Upcoming SlideShare. Like this presentation? Why not share! An annual anal Embed Size px. Start on. Show related SlideShares at end. WordPress Shortcode. Published in: Full Name Comment goes here.
Are you sure you want to Yes No. Be the first to like this. No Downloads. Views Total views. Swift checks that is a valid value for an Int8.
But Int8 can only hold values from to When your playground runs. Your playground therefore hits a trap. Swift provides overflow operators that have different behaviors when the value is too big or too small. Click on it to see a more detailed message Figure 4. The philosophy of the Swift language is that it is better to trap even though this may result in a program crashing than potentially have a security hole.
Swift is designed to prioritize safety and minimize these errors. Integer operations overflowing or underflowing unexpectedly can be a source of serious and hard-to-find bugs. There are some use cases for wrapping arithmetic. There are also overflow versions of the subtraction and multiplication operators: It should be apparent why there is an overflow version of the multiplication operator. Subtraction clearly cannot overflow.
The increase in verbosity will make it easier for you to reason about and maintain the code. Reread the previous section! Requiring you. This is a compile-time error. Some languages will automatically convert types for you to perform operations like this. Using Int consistently throughout your code will greatly reduce the need for you to convert types. What happens if you try to operate on numbers with different types?
The C programming language. Swift code that requires math between numbers of different types will be more verbose. You cannot add a and b because they are not of the same type. Converting Between Integer Types So far. Swift does not. As you might expect. More on that in a moment. The default inferred type for floating-point numbers in Swift is Double.
There are two things to bear in mind about floating-point numbers. For example.. Double has more precision than Float. As with different types of integers. Floating-Point Numbers To represent a number that has a decimal point. The different bit sizes of Float and Double do not determine a simple minimum and maximum value range as they do for integers.
The computer will store a very close approximation to the number you expect. Swift has two basic floating-point number types: There are many numbers that cannot be stored with perfect accuracy in a floating-point number. But they are not technically equal. One consequence is that you should never use floating-point numbers for values that must be exact such as calculations dealing with money. There are other tools available for those purposes. When you add 1. The moral of this story is to be aware that there are some potential pitfalls with floating-point numbers.
The value stored when you typed the literal 1. All the gory details behind floating-point arithmetic are outside the scope of this book. As we said before.
You would expect that to result in 1. So far. Why not? Swift will round both of those to 1. Bronze Challenge Set down your computer and grab a pencil and paper for this challenge. What is the binary representation of -1 using an 8-bit signed integer? If you took that same bit pattern and interpreted it as an 8-bit unsigned integer.
This chapter looks at the switch statement. What Is a Switch? In contrast, switch statements consider a particular value and attempt to match it against a number of cases. If there is a match, the switch executes the code associated with that case. Here is the basic syntax of a switch statement: If aValue matches any of the comparison cases, then the body of that case will be executed.
Notice the use of the default case. It is executed when the comparison value does not match any of the cases. The default case is not mandatory.
However, it is mandatory for switch statements to have a case for every value of the type being checked. So it is often efficient to use the default case rather than providing a specific case for every value in the type. As you might guess, in order for the comparisons to be possible the type in each of the cases must match the type being compared against.
This code shows the basic syntax of a switch statement, but it is not completely well formed. In fact, this switch statement would cause a compile-time error. If you are curious, type it into a playground and see.
Give aValue and all of the cases values. You should see an error for each of the cases, telling you "'case' label in a 'switch' should have at least one executable statement. This is the purpose of a switch statement: Each case should represent a separate branch of execution. In the example, the cases only have comments under them.
Because comments are not executable, the switch statement does not meet this requirement. Switch It Up Create a new playground called Switch and set up a switch. Listing 5. Because case matches statusCode, errorString is assigned to be equal to "Not found", as you can see in the sidebar Figure 5. Try changing the value of statusCode to see the other results. When you are done, set it back to Suppose you want to use a switch statement to build up a meaningful error description. Update your code as shown.
If the statusCode matches any of the values in the case, the text "There was something wrong with the request. You have also added a control transfer statement called fallthrough. Control transfer statements allow you to modify the order of execution in some control flow.
These statements transfer control from one chunk of code to another. You will see another way to use control transfer statements in Chapter 6 on looping. If a matching case has a fallthrough control transfer statement at the end of it, it will first execute its code, and then transfer control to the case immediately below.
That case will execute its code — whether or not it matches the value being checked against. If it also has a fallthrough statement at the end, it will hand off control to the case below, and so on. In this example, because of the fallthrough statement, the switch statement does not stop, even though the first case matches.
Instead, it proceeds to the default case. Without the fallthrough keyword, the switch statement would have ended execution after the first match. The use of fallthrough in this example allows you to build up errorString without having to use strange logic that would guarantee that the comparison value matched all of the cases of interest.
The end result of this switch statement is that errorString is set to "There was something wrong with the request. Please review the request and try again. If you match on a case, the case executes its code and the switch stops running. You have seen switch statements in which the cases have a single value to check against the comparison value and others in which the cases have multiple values.
Update your code to see this in action. That is, You also have cases with a single HTTP status code the second case and with two codes explicitly listed and separated by a comma the first case , as well as a default case. These are formed in the same way as the cases you saw before.
All of the case syntax options can be combined in a switch statement. The result of this switch statement is that errorString is set to equal "The request failed with the error: Client error, 4xx. Be sure to set it back to before continuing. Suppose you want to include the actual numerical status codes in your errorString, whether the status code is recognized or not.
Value binding allows you to bind the matching value in a certain case to a local constant or variable. Take a closer look at the last case.
When the statusCode does not match any of the values provided in the cases above, you create a temporary constant, called unknownCode, binding it to the value of statusCode. For example, if the statusCode were set to be equal to , then your switch would set errorString to be equal to " is not a known error code. Note that by using a constant, you fix the value of unknownCode. If you needed to do work on unknownCode, for whatever reason, you could have declared it with var instead of let.
This example shows you the syntax of value binding, but it does not really add much. The standard default case can produce the same result. Replace the final case with a default case. This meant that the final case by definition matched everything that had not already matched a case in the switch statement. The switch statement was, therefore, exhaustive. When you deleted the final case, the switch was no longer exhaustive. This means that you had to add a default case to the switch.
The code above is fine, but it is not great. After all, a status code of is not really an error — represents success! Therefore, it would be nice if your switch statement did not catch these cases. To fix this, use a where clause to make sure unknownCode is not a 2xx indicating success.
This feature creates a sort of dynamic filter within the switch. This is not a problem because you already have a default case in the switch. When statusCode is equal to , the switch will match at the second case and the errorString will be set accordingly. So, even though is within the range specified in the where clause, the switch statement never gets to that clause. Change statusCode to exercise the where clause and confirm that it works as expected. Now that you have your statusCode and errorString, it would be helpful to pair those two pieces.
Although they are logically related, they are currently stored in independent variables. A tuple can be used to group the two. A tuple is a finite grouping of two or more values that are deemed by the developer to be logically related.
The different values are grouped as a single, compound value. The result of this grouping is an ordered list of elements. Create your first Swift tuple that groups the statusCode and errorString. You made a tuple by grouping statusCode and errorString within parentheses.
The result was assigned to the constant error. The elements of a tuple can be accessed by their index. You might have noticed. Type in the following to access each element stored inside of the tuple. It is not very easy to keep track of what values are represented by error.
Named elements allow you to use easier-to-parse code like error. Your results sidebar should have the same information displayed. This form of pattern matching is called interval matching because each case attempts to match a given interval against the comparison value.
Tuples are also helpful in matching patterns. Imagine, for example, that you have an application that is making multiple web requests. Add the following code to create and switch on a new tuple. The new switch statement matches against several cases to determine what combination of s the requests might have yielded.
The first case will match only if both of the requests failed with error code The second case will match only if the first request failed with The third case will match only if the second request failed with Finally, if the switch has not found a match, that means none of the requests failed with the status code Because firstErrorCode did have the status code , you should see "First item not found.
Sometimes you might be tempted to use a switch statement on a value that could potentially match against any number of cases, but you really only care about one of them. For example, imagine checking an age constant of type Int looking for a specific demographic: You might think writing a switch statement with a single case is your best option: It is possible that age could take on any value between 0 and or so, but you are only interested in a particular range.
The switch checks to see whether age is in the range from 18 to If it is, then age is in the desired demographic and some code is executed. Otherwise, age is not in the target demographic and the default case matches, which simply transfers the flow of execution outside of the switch with the break control transfer statement.
Notice that you had to include a default case; switch statements have to be exhaustive. If this does not feel quite right to you, we agree. You do not really want to do anything here, which is why you used a break.
It would be better to not have to write any code when you do not want anything to happen! Swift provides a better way. Swift also has an if-case statement that provides pattern matching similar to what a switch statement offers.
After the comma. They also enjoy all of the pattern-matching power that make switch statements so wonderful. In the United States. You did not have to write a default case that you did not care about Use an if-case when you have only one case in mind for a switch and you do not care about the default case.. It simply checks to see whether age is in the given range. Bronze Challenge Review the switch statement below. What will be logged to the console? After you have decided. Silver Challenge You can add more conditions to the if-case by supplying a comma-separated list.
Add another condition to Listing 5. Loops can save you from writing tedious and repetitive code. Each type of loop has variations. They execute a set of code repeatedly. You will be using them a lot in your development. In this chapter. You next declare an iterator called i that represents the current iteration of the loop. You can think of i as being replaced with a new constant set to the next value in the range at the beginning of each iteration.
In the first iteration of the loop. Create a loop as shown. In the second iteration The for keyword signals that you are writing a loop. After incrementing myFirstInt. This loop is represented in Figure 6. These two steps — incrementing and logging — continue until i reaches the end of the range: The iterator is constant within the body of the loop and only exists here.
For each iteration. You then log this value to the console. Listing 6. Because you used. Move your mouse pointer into this new window and you will see that you can select individual points on this plot. You can grow or shrink the window of the graph by clicking and dragging its edges. Figure 6. It does not check and report the value of the iterator in each pass of the loop over its range.
Replace your named constant with this wildcard and return your print statement to its earlier implementation. Change your output to show the value of i at each iteration. The where clause then checks to see whether i is divisible by 3. The result is that the loop will print out every multiple of 3 from 1 to If the remainder is 0. If the condition established by the where clause is not met. Using where allows for finer control over when the loop executes its code. Each integer in the range of 1 to is bound to i.
Imagine how you might accomplish this same result without the help of a where clause.. There are more lines of code and there is a nested conditional within the loop.
Generally speaking. It could be. In this example. We will highlight those when they come up. In general. The type of i is inferred from its context as is the let.. Type inference is handy: Because you will type less.. Int in 1.
Loops that never end are called infinite loops. You can write while loops to do many of the same things you have seen in for loops above. But if the shields have a value greater than 0. The code snippet below illustrates a simplified implementation of this idea.
It would not even get to fire a shot. The repeat-while loop avoids a somewhat depressing scenario: What if the spaceship is created and. A repeat-while loop ensures that the blasters fire at least once to avoid this anticlimactic scenario. The repeat-while loop. The difference between while and repeat- while loops is when they evaluate their condition.
The syntax for the repeat-while loop demonstrates this difference. That would be a pretty poor user experience. The repeat-while loop is called a do-while loop in other languages. This means that the while loop may not ever execute. Perhaps it spawns in front of an oncoming asteroid. The while loop evaluates its condition before stepping into the loop. Control Transfer Statements. You are going to use the continue control transfer statement to stop the loop where it is and begin again from the top.
Recall from Chapter 5 where you used fallthrough and break that control transfer statements change the typical order of execution. In the context of a loop. Cooldown initiated. The first if statement checks whether the blasters are overheating.
You use continue to do this. You next log that the blasters are ready to fire again. For the first. At this point. With shields intact and blasters cooled down.
The second if statement checks whether blasterFireCount is greater than After you increment this variable. After creating your variables. You log information to the console and the sleep function tells the system to wait for 5 seconds. If this conditional evaluates to true. If the second conditional is evaluated to be false. But all games must come to an end.. There is nothing to change the value of shields. If nothing changes. This is what we call an infinite loop. To exit the loop.
Note that this code will execute indefinitely. This makes sense: If the user has destroyed space demons and the game is won. You are a pretty good shot. Note the use of break.
The break control transfer statement will exit the while loop. If it is. If the number is evenly divisible by 5. When using the switch. Silver Challenge Fizz Buzz is a game used to teach division.
The game is perfect for loops and conditionals. For bonus points. Create a version of the game that works like this: For every value in a given range.
You have seen and used strings already. Like all strings. In reality. Swift strings are not themselves collections. Loop through the mutablePlayground string to see the Character type in action. Create a new string. Create a new playground called Strings and add the following new instance of the String type. Listing 7. In other words. Working with Strings In Swift. You should see that the instance has changed to "Hello..
This instance was created with the let keyword. Use the addition and assignment operator to add some final punctuation. Recall that being a constant means that the instance cannot be changed. If you do try to change it. Do not worry about what a property is right now. Figure 7. Every character is logged to the console on its own line because print prints a line break after logging its content.
Your output should look like Figure 7. In it. Character in mutablePlayground. The characters property represents the collection of characters that make up the instance. Unicode represents human language and other forms of communication like emoji on computers. Every character in the standard is assigned a unique number. Unicode scalars At their heart.
Create a constant to see how to use specific Unicode scalars in Swift and the playground. Unicode scalars are bit numbers that represent a specific character in the Unicode standard. The quotation marks are familiar. Having this knowledge will likely save you some time and frustration in the future.
The 1F60E portion is a number written in hexadecimal. It does not match the results in the sidebar Figure 7. Unicode Unicode is an international standard that encodes characters so they can be seamlessly processed and represented regardless of the platform. Extended grapheme clusters are sequences of one or more Unicode scalars that combine to produce a single human-readable character. This scalar is placed on top of — that is. So why do they look unfamiliar?
To explain. One Unicode scalar maps onto one fundamental character in a given language. In this case.. Just now. How does this relate to more familiar strings? It turns out that every string in Swift is composed of Unicode scalars. Every character in Swift is an extended grapheme cluster. Every character in Swift is built up from one or more Unicode scalars. Making characters extended grapheme clusters gives Swift flexibility in dealing with complex script characters.
Unicode also provides already combined forms for some common characters. But they are not the hexadecimal Unicode numbers. What do all of these numbers mean? Recall that the unicodeScalars property holds on to data representing all of the Unicode scalars used to create the string instance playground.
Each number on the console corresponds to a Unicode scalar representing a single character in the string. The first. Swift also provides a mechanism to see all of the Unicode scalars in a string. You do not actually need to decompose it into its two parts: Create a new constant string that uses this Unicode scalar.
Why does Swift say that they are equivalent? The answer is canonical equivalence. Two characters. The fact that they were created with different Unicode scalars does not affect this. Write the following code to check. You might think that aAcute and aAcutePrecomposed would have different character counts. Canonical equivalence refers to whether two sequences of Unicode scalars are the same linguistically..
Counting elements Canonical equivalence has implications for counting elements of a string. This limitation has to do with the way Swift strings and characters are stored. The results sidebar reveals that the character counts are the same: Both are 1 character long.
You will read more about nested types in Chapter Do not worry about all of the periods. It is convenient to have Index defined on CharacterView. The code playground uses the subscript syntax. Indices and ranges Because strings can be thought of as ordered collections of characters.
Swift forces you to be more explicit. This allows you to ask the character view to hand back indices that are meaningful for the string in question. Subscripts allow you to retrieve a specific value within a collection.
You cannot index a string with an integer because Swift does not know which Unicode scalar corresponds to a given index without stepping through every preceding character. Index to keep track of indices. This operation can be expensive. Swift uses a type called String.
As you have seen in this chapter. Canonical equivalence means that whether you use a combining scalar or a precomposed scalar. You will learn more about subscripts below and will also see them in action in Chapter 9 and Chapter 10 on arrays and dictionaries. It is the job of the CharacterView to represent each of these code points as a single Character instance and to combine these characters into the correct string.
This property yields the starting index of a string as a. The code above suggests that you are trying to select the fourth character from the collection of characters making up the playground string the first index is 0. If you tried to use a subscript like this. A method is like a function. You can use the same start and end constants. This property yields an instance of type String. Say you want to know the fifth character of the playground string that you created at the beginning of this chapter.
The offsetBy parameter takes an argument of type Int. The subscript grabbed the first five characters from playground. You passed in 4 to represent the fifth character. Imagine that you wanted to grab the first five characters of playground. You used this new range as a subscript on the playground string.
Index that you assigned to the constant end. Index type. It is useful to be able to tell if a string has any characters in it. Bronze Challenge Create a new String instance called empty and give it an empty string: Use the startIndex and endIndex properties on empty to determine whether this string is truly empty. You can find the appropriate codes on the internet. Silver Challenge Replace the "Hello" string with an instance created out of its corresponding Unicode scalars.
It either has a value and it is ready for use. This feature distinguishes Swift from Objective-C. You can use optionals with any type to signal that an instance is potentially nil.
This chapter covers how to declare optional types. If an instance has no value associated with it. When you see an optional. This time you put a? An instance that may potentially be nil should be declared to be an optional type. Optional Types Optionals in Swift make the language safer. Create a new playground and name it Optionals.
This way. You can use. Enter the code snippet below. Listing 8. This means that if an instance is not declared as an optional type. What would happen if you did not give errorCodeString a value? Try it! Comment out the line assigning a value to errorCodeString. This explicit declaration makes your code more expressive and safe. Now that you have declared an optional and given it a value.
But logging nil to the console is not very helpful. The exclamation mark here does what is called forced unwrapping. In the next line. You set up a conditional with code that executes if errorCodeString is not nil remember that! If there is no value inside the optional. If you had omitted the exclamation mark at the end of errorCodeString. The optional errorCodeString was nil when it was first declared because it was given no value.
You can compare an. Forced unwrapping accesses the underlying value of the optional. The value of theError would still have been logged to the console correctly.
Add the following code to your playground. To do this.
The answer requires a better understanding of the optional type. In the body of the conditional.
There is some danger in forced unwrapping. It is called optional binding. Creating a constant inside the conditional is a little clunky. In the code above. This can make your code more concise while also retaining its expressive nature. Imagine that you wanted to convert errorCodeString to its corresponding integer representation. Optional Binding Optional binding is a useful pattern that you can use to detect whether an optional contains a value.
You could accomplish this by nesting if let bindings. If the conversion is successful. Here is the basic syntax: This makes theError a temporary constant that is available within the first branch of the conditional. The constant theError moves from the body of the conditional to its first line. If there is a value. The result of Int theError is unwrapped and assigned to errorCodeInteger in the second binding.
This feature helps you avoid the need for nesting multiple if let calls — nasty code like you saw above and worse. In the example above. Optional binding can even perform additional checks that work very similarly to what you have already seen with standard if statements.
Nesting optional binding can be convoluted. This operation can fail. While it is not too bad with just a couple of optionals. You use Int theError to try to convert theError into an Int. Because this results in an optional. You can then use both of these new constants in a call to print to log them to the console.
If either of these bindings return nil. Int theError returns an optional. Imagine that you only care about an error code if the value is Because theError is "".
Implicitly unwrapped optionals are like regular optional types. For this reason. The conditional is removed because using an implicitly unwrapped optional signifies a great deal more confidence than its more humble counterpart.
Accessing the value of an implicitly unwrapped optional will result in a runtime error if it does not have a value. What would happen if you declared a constant named anotherErrorCodeString with type String and tried to assign to it the contents or lack thereof of errorCodeString? If you were to assign errorCodeString to another instance. Take a look at the code below. Implicitly Unwrapped Optionals At this point it is worth mentioning implicitly unwrapped optionals. If errorCodeString is nil.
How is that the case? It has to do with how you declare them. You do not need to unwrap them. Because anotherErrorCodeString cannot be optional. Suppose you set errorCodeString to be nil. Using implicitly unwrapped optionals is best limited to somewhat special cases.
Swift will infer the safest thing possible: If you want yetAnotherErrorCodeString to be an implicitly unwrapped optional. This feature makes type inference safe by default and thereby suppresses the unintended proliferation of unsafe code.
You would have to unwrap the optional to access its value. As we indicated. You need to declare that the type of optional that you want is implicitly unwrapped. As for the second question. Optional Chaining Like optional binding. If any optional in the query chain is nil.
The results sidebar should display the updated value: If you encounter a The question mark appended to the end of errorDescription signals that this line of code initiates the optional chaining process. Imagine that your app has a custom error code for some reason. When you created the interpolated string. If there is no value in errorDescription. If each optional in the chain contains a value.
Because errorDescription does have a value in it. Inside of the if let success block. Add the following to your playground. This point demonstrates that optional chaining will return an optional. This instance is called upCaseErrorDescription. You did not need anything returned. If upCaseErrorDescription were nil. This operation would forcibly unwrap the optional — which can be dangerous. As you have read above.
If there was no value. Modifying an Optional in Place You can modify an optional in place so that you do not have to create a new variable or constant. This is exactly what modifying an optional in place does. It exposes the value of the optional if it exists. It is worth mentioning that you can also use the!
If there was a value inside of the optional. You had to write a lot of code for what should be a simple operation: Get the value from the optional or use "No error" if the optional is nil. If the lefthand side optional is nil. The righthand side must be a nonoptional of the same type — "No error". Optionals are a new topic regardless of your level of development experience.
Try changing errorDescription so that it does not contain an error and confirm that description gets the value "No error". This can be solved via the nil coalescing operator: The Nil Coalescing Operator A common operation when dealing with optionals is to either get the value if the optional contains a value or to use some default value if the optional is nil.
You could accomplish this with optional binding. You learned a lot of new material. They are also a powerful feature of. If the lefthand side optional is not nil.
As a developer. If optionals do not quite feel comfortable yet. You will be seeing them quite a bit in future chapters. Optionals help you keep track of whether instances are nil and provide a mechanism to respond appropriately. Bronze Challenge Optionals are best used for things that can literally be nil. Take a look at the examples below and select which type would model them best.
The number of kids a parent has: Int or Int? String or String? But nonexistence is not the same as zero. Make this mistake by force-unwrapping an optional when it is nil.
Swift provides functions to help developers transform data into something meaningful for the user or accomplish some other task.