Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - iOS Programming

64 Articles
article-image-iphone-javascript-installing-frameworks
Packt
23 Jun 2011
14 min read
Save for later

iPhone JavaScript: Installing Frameworks

Packt
23 Jun 2011
14 min read
  iPhone JavaScript Cookbook Clear and practical recipes for building web applications using JavaScript and AJAX without having to learn Objective-C or Cocoa         Read more about this book       (For more resources related to this subject, see here.) Introduction Many web applications implement common features independent of the final purpose for which they have been designed. Functionalities and features such as authentication, forms validation, retrieving records from a database, caching, logging, and pagination are very common in modern web applications. As a developer, surely you have implemented one or more of these features in your applications more than once. Good developers and software engineers insist on concepts, such as modularity, reusability, and encapsulation; as a consequence you can find a lot of books, papers, and articles talking about how to design your software using these techniques. In fact, modern and popular methodologies, such as Extreme Programming, Scrum, and Test-driven Development are based on those principles. Although this approach sounds very appealing in theory, it might be complicated to carry it out in practice. Developing any kind of software from scratch for running in any platform is undoubtedly a hard task. Complexity grows up when the target platform, operating system, or machine has its own specific rules and mechanisms. Some tools can make our job less complicated but only one kind of them is definitely a safe bet. It is here when we meet frameworks, a set of proven code that offers common functionality and standard structures for software development. This code makes our life much easier without reinventing the wheel and gives a skeleton to our applications, making sure that we're doing things correctly. In addition, frameworks avoid starting from scratch once more. From a technical point of view, most frameworks are a set of libraries implementing functions, classes, and methods. Using frameworks, we can save time and money, writing less code due to its code skeleton, and features implemented on it. Usually, frameworks force us to follow standards and they offer well-proven code avoiding common mistakes for beginners. Tasks such as testing, maintenance, and deployment are easier to do using frameworks due to the tools and mechanisms included. On the other hand, the learning curve could be a big and difficult drawback for beginners. Through this article, we'll learn how to install the main frameworks for JavaScript, HTML, and CSS development for iPhone. All of them offer a base to develop applications with a consistent and native look and feel using different methods. While some of them are focused on the user interface, others allow using AJAX in an efficient and easy way. Even some frameworks allow building native applications from the original code of the web application. We have the chance to choose which is better to fulfill our requirements; it is even possible to use more than one of these solutions for the same application. For our recipes, we'll use the following frameworks: iUI: This is focused on the look and feel of iPhone and consists of CSS files, images, and a small JavaScript library. Its objective is to get a web application running on the device with a consistent interface such as a native application. This framework establishes a correspondence between HTML tags and conventions used for developing native applications. UiUIKit: Using a set of CSS and image files, it provides a coherent system for building web applications with a graphic interface such as native iPhone applications. The features offered for this framework are very similar to iUI. XUI: This is a pure JavaScript library specific for mobile development. It has been designed to be faster and lighter than other similar libraries, such as jQuery, MooTools, and prototype. iWebKit: This is developed specifically for Apple's devices and is compatible with CSS3 standard; it helps to write web applications or websites with minimum HTML knowledge. Its modular design supports plugins for adding new features and we can build and use the themes for UI customization. WebApp.Net: This framework comes loaded with JavaScript, CSS, and image files for developing web application for mobile devices that uses WebKit engine in its web browsers. Besides building interfaces, this framework includes functionality to use AJAX in an easy and efficient way. PhoneGap: This is designed to minimize efforts for developing native mobile applications for different operating systems, platforms, and devices. It is based on the WORE (Write once, run anywhere) principle and it allows conversion from a web application into a native application. It supports many platforms and operating systems, such as iOS, Android, webOS, Symbian, and BlackBerry OS. Apple Dashcode: Formally, this is a software development tool for Mac OS X included in Leopard and Snow Leopard versions, and focused on widget development for these operating systems. However, the last versions allow you to write web applications for iPhone and other iOS devices offering a graphic interface builder. Installing the iUI framework This recipe shows how to download and install the iUI framework on different operating systems. Particularly, we'll cover Microsoft Windows, Mac OS X, and GNU/Linux. Getting ready The first step is to install and get ready; some tools need to be downloaded and decompressed. As computer users, we know how to decompress files using software such as WinZip, Ark, or the built-in utility on Mac OS X. You will surely have installed a web browser on your computer. If you are a Linux or Mac developer, you already know how to use curl or wget. These tools are very useful for quick download and you only need to use the command line through applications such as GNOME Terminal, Konsole, iTerm, or Terminal. iUI is an open source project, so you can download the code for free. The open source project releases some stable versions packed and ready to download, but it is also possible to download a development version. This one could be suitable if you prefer working with the latest changes made by the official developers contributing to the project. Due to this, developers are using Mercurial version control and thus we'll need to install a client for it to get access to this code. How to do it... iUI is an open source project so you can download the code for free. Open your favorite web browser and enter this URL: http://code.google.com/p/iui/downloads/list In that web page, you'll see a list with files that refer to different release versions of this framework. Clicking on the link corresponding to the latest release's drives takes you to a new web page that shows you a new link for the file. Click on it for instant downloading. (Move the mouse over the image to enlarge it.) If you are a GNU/Linux user or a Mac developer you will be used to command line. Open your terminal application and launch this command from your desired directory: $ wget http://iui.googlecode.com/files/iui-0.31.tar.gz Once you have downloaded the tarball file, it's time to extract its content to a specific folder on our computer. WinZip and WinRAR are the most popular tools to do this task on Windows. Linux distributions, by default, install similar tools such as File Roller and Ark. Double-clicking from the download window of the Safari browser will extract the files directly to your default folder on your Mac, which is usually called Downloads. For command-line enthusiasts, execute the following command: $ tar -zxvf iui-0.31.tar.gz How it works... After decompressing the downloaded file, you'll find a folder with different subfolders and files. The most important is a subfolder called iui that contains CSS, images, and JavaScript files for building our web applications for iPhone. We need to copy this subfolder to our working folder where other application files reside. Sharing this framework across different web applications is possible; you only need to put the iUI at a place where these applications have permissions to access. Usually, this place is a folder under the DocumentRoot of your web server. If you're planning to write a high load application, it would be a good idea to use a cloud or CDN (Content Delivery Network) service such as Amazon Simple Storage Services (Amazon S3) for hosting and serving static HTML, CSS, JavaScript, and image files. Installing the iUI framework is a straightforward process. You simply download and decompress one file, and then copy one folder into an other, which has permission to be accessed by the web server. Apache is one of the most used and extended web servers in the world. Other popular options are Internet Information Server (IIS), lighttpd, and nginx. Apache web server is installed by default on Mac OS X; most of the operating systems based on Linux and UNIX offer binary packages for easy installation and you can find binary files for installing on Windows as well. IIS was designed for Windows operating systems, meanwhile, lighttpd and nginx are winning popularity and are used on UNIX systems as Linux's distros, FreeBSD, and OpenBSD. Ubuntu Linux uses /var/www/ directory as the main DocumentRoot for Apache. So, in order to share iUI framework across applications, you can copy the folder to the other folder by executing this command: $ cp -r iui-0.31/ui /var/www/iui If you are a Mac user, your target directory will be /Library/WebServer/Documents/iui. There's more... Inside the samples subfolder, you'll find some files showing capabilities of this framework, including HTML and PHP files. Some examples need a web server with PHP support but you can test others using Safari web browser or an other WebKit's browser such as Safari or Google Chrome. Open index.html with a web browser and use it as your starting point. If you prefer to use the latest version in development from the version control, you'll need to install a Mercurial client. Most of the GNU/Linux distribution such as Fedora, Debian, and Ubuntu includes binary packages ready to install them. Usually, the name of the binary package is mercurial. The following command will install the client on Ubuntu Linux: $ sudo apt-get install mercurial Mercurial is an open source project and offers a binary file ready to install for Mac OS X and Windows systems. If you're using one of these, go to the following page and download the specific file for your operating system and version: http://mercurial.selenic.com/downloads/ After downloading, you can install the client using the regular process for your operating system. Mac users will find a ZIP file containing a binary package. For Windows, the distributed file is a MSI (Microsoft Installer), ready for self-installation after clicking on it. Despite that the client of this version control was developed for the command line, we can find some GUI tools online such as TortoiseHG for Windows. These tools are intuitive and user-friendly, allowing an interactive use between the user and the source files hosted in the version control system. TortoiseHG can be downloaded from the same web page as the Mercurial client. Finally, we'll download the version development of the iUI framework executing the following command: $ hg clone https://iui.googlecode.com/hg/ iui The new iui folder includes all files of the iUI framework. We should copy this folder to our DocumentRoot. If you want to know more about this framework, point your browser at the official wiki project: http://code.google.com/p/iui/w/list Also, taking a look at the complete code of the project may be interesting for advanced developers or just for people wanting to learn more about internal details: http://code.google.com/p/iui/source/browse Installing the UiUIKit framework UiUIKit is the short name of the Universal iPhone UI Kit framework. The development of this framework is carried out through an open source project hosted in Google Code and is distributed under the GNU Public License v3. Let's see how to install it on different operating systems. Getting ready As the main project file is distributed as a ZIP file, we'll need to use one tool for decompressing these kind of files. Most of the modern operating systems include tools for this process. As seen in the previous recipe, we can use wget or curl programs for downloading the files. If you are planning to read the source code or you'd like to use the current development version of the framework, you'll need a Subversion client as the UiUIKit project is working with this open source version control. How to do it... Open your web browser and type the following URL: http://code.google.com/p/iphone-universal/downloads/list After downloading, click on the link for the latest version from the main list, for instance, the link called UiUIKit-2.1.zip. The next page will show you a different link for this file that represents the version 2.1 of the UiUIKit framework. Click on the link and the file will start downloading immediately. Mac users will see how the Safari browser shows a window with the content of the compressed file, which is a folder called UiUIKit, which is stored in the default folder for downloads. Command line's fans can use these simple commands from their favorite terminal tool: $ cd ~$ curl -O http://iphone-universal.googlecode.com/files/UiUIKit-2.1.zip After downloading, don't forget to decompress the file on your web-specific directory. The commands given next execute this action on Linux and Mac OS X systems: $ cd /var/www/$ unzip ~/UiUIKit-2.1.zip How it works... The main folder of the UiUIKit framework contains two subfolders called images and stylesheets. The first one includes many images used to get a native look for web applications on the iPhone. The other one offers a CSS file called iphone.css. We only need the images subfolder with its graphic files and the CSS file. In order to use this framework in our projects, we need to allow our HTML files access to the images and the CSS file of the framework. These files should be in a folder with permissions for the web server. For example, we'll have a directory structure for our new web application for iPhone as follows: myapp/ index.html images/ actionButtons.png apple-touch-icon.png backButton.png toolButton.png whiteButton.png first.html second.html stylesheets/ iphone.css Remember that this framework doesn't include HTML files; we only need a bunch of the graphic files and one stylesheet file. The HTML files showed in the previous example will be our own files created for the web application. We'll also find a lot of examples on different HTML files located in the root directory, outside the mentioned subfolders. These files are not required for development but they can be very useful to show how to use some features and functionalities. There's more... For an initial contact with the capabilities of the framework it would be interesting to take a look at the examples included in the main directory of the framework. We can load the index.html in our browser. This file is an index to the different examples and offers a native interface for the iPhone. Safari could be used but is better to access from a real iPhone device. Subversion is a well-proven version control used by many developers, companies, and, of course, open source projects. UiUIKit is an example of these projects using this popular version control. So, to access the latest version in development, we'll need a client to download it. Popular Linux distributions, including Ubuntu and Debian have binary packages ready to install. For instance, the following command is enough to install it on Ubuntu Linux: $ sudo apt-get install subversion The last versions of Mac OS X, including Leopard and Snow Leopard, includes a Subversion client ready to use. For Windows, you can download Slik SVN available for 32-bit and 64-bits platforms; installation programs can be downloaded from: http://www.sliksvn.com/en/download. When you are sure that your client is running, you could execute it for getting the latest development version of the UiUIKit framework. Mac and Linux users will execute the following command: $ svn checkout http://iphone-universal.googlecode.com/svn/trunk/ UiUIKit All information related to the UiUIKit framework project could be found at: http://code.google.com/p/iphone-universal/
Read more
  • 0
  • 0
  • 8652

article-image-your-first-swift-2-project
Packt
16 Feb 2016
29 min read
Save for later

Your First Swift 2 Project

Packt
16 Feb 2016
29 min read
After the release of Xcode 6 in 2014, it has been possible to build Swift applications for iOS and OS X and submit them to the App Store for publication. This article will present both a single view application and a master-detail application, and use these to explain the concepts behind iOS applications, as well as introduce classes in Swift. In this article, we will present the following topics: How iOS applications are structured Single-view iOS applications Creating classes in Swift Protocols and enums in Swift Using XCTest to test Swift code Master-detail iOS applications The AppDelegate and ViewController classes (For more resources related to this topic, see here.) Understanding iOS applications An iOS application is a compiled executable along with a set of supporting files in a bundle. The application bundle is packaged into an archive file to be installed onto a device or upload to the App Store. Xcode can be used to run iOS applications in a simulator, as well as testing them on a local device. Submitting an application to the App Store requires a developer signing key, which is included as part of the Apple Developer Program at https://developer.apple.com. Most iOS applications to date have been written in Objective-C, a crossover between C and Smalltalk. With the advent of Swift, it is likely that many developers will move at least parts of their applications to Swift for performance and maintenance reasons. Although Objective-C is likely to be around for a while, it is clear that Swift is the future of iOS development and probably OS X as well. Applications contain a number of different types of files, which are used both at compile time and also at runtime. These files include the following: The Info.plist file, which contains information about which languages the application is localized for, what the identity of the application is, and the configuration requirements, such as the supported interface types (iPad, iPhone, and Universal), and orientations (Portrait, Upside Down, Landscape Left, and Landscape Right) Zero or more interface builder files with a .xib extension, which contain user interface screens (which supersedes the previous .nib files) Zero or more image asset files with a .xcassets extension, which store groups of related icons at different sizes, such as the application icon or graphics for display on screen (which supersedes the previous .icns files) Zero or more storyboard files with a .storyboard extension, which are used to coordinate between different screens in an application One or more .swift files that contain application code Creating a single-view iOS application A single-view iOS application is one where the application is presented in a single screen, without any transitions or other views. This section will show how to create an application that uses a single view without storyboards. When Xcode starts, it displays a welcome message that includes the ability to create a new project. This welcome message can be redisplayed at any time by navigating to Window | Welcome to Xcode or by pressing Command + Shift + 1. Using the welcome dialog's Create a new Xcode project option, or navigating to File | New | Project..., or by pressing Command + Shift + N, create a new iOS project with Single View Application as the template, as shown in the following screenshot: When the Next button is pressed, the new project dialog will ask for more details. The product name here is SingleView with appropriate values for Organization Name and Identifier. Ensure that the language selected is Swift and the device type is Universal: The Organization Identifier is a reverse domain name representation of the organization, and the Bundle Identifier is the concatenation of the Organization Identifier with the Product Name. Publishing to the App Store requires that the Organization Identifier be owned by the publisher and is managed in the online developer center at https://developer.apple.com/membercenter/. When Next is pressed, Xcode will ask where to save the project and whether a repository should be created. The selected location will be used to create the product directory, and an option to create a Git repository will be offered. In 2014, Git became the most widely used version control system, surpassing all other distributed and centralized version-control systems. It would be foolish not to create a Git repository when creating a new Xcode project. When Create is pressed, Xcode will create the project, set up template files, and then initialize the Git repository locally or on a shared server. Press the triangular play button at the top-left of Xcode to launch the simulator: If everything has been set up correctly, the simulator will start with a white screen and the time and battery shown at the top of the screen: Removing the storyboard The default template for a single-view application includes a storyboard. This creates the view for the first (only) screen and performs some additional setup behind the scenes. To understand what happens, the storyboard will be removed and replaced with code instead. Most applications are built with one or more storyboards. The storyboard can be deleted by going to the project navigator, finding the Main.storyboard file, and pressing the Delete key or selecting Delete from the context-sensitive menu. When the confirmation dialog is shown, select the Move to Trash option to ensure that the file is deleted rather than just being removed from the list of files that Xcode knows about. To see the project navigator, press Command + 1 or navigate to View | Navigators | Show Project Navigator. Once the Main.storyboard file has been deleted, it needs to be removed from Info.plist, to prevent iOS from trying to open it at startup. Open the Info.plist file under the Supporting Files folder of SingleView. A set of key-value pairs will be displayed; clicking on the Main storyboard file base name row will present the (+) and (-) options. Clicking on the delete icon (-) will remove the line: Now, when the application is started, a black screen will be displayed. There are multiple Info.plist files that are created by Xcode's template; one file is used for the real application, while the other files are used for the test applications that get built when running tests. Setting up the view controller The view controller is responsible for setting up the view when it is activated. Typically, this is done through either the storyboard or the interface file. As these have been removed, the window and the view controller need to be instantiated manually. When iOS applications start, application:didFinishLaunchingWithOptions: is called on the corresponding UIApplicationDelegate. The optional window variable is initialized automatically when it is loaded from an interface file or a storyboard, but it needs to be explicitly initialized if the user interface is being implemented in code. Implement the application:didFinishLaunchingWithOptions: method in the AppDelegate class as follows: @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {   var window: UIWindow?   func application(application: UIApplication,    didFinishLaunchingWithOptions launchOptions:    [NSObject:AnyObject]?) -> Bool {     window = UIWindow()     window?.rootViewController = ViewController()     window?.makeKeyAndVisible()     return true   } } To open a class by name, press Command + Shift + O and type in the class name. Alternatively, navigate to File | Open Quickly... The final step is to create the view's content, which is typically done in the viewDidLoad method of the ViewController class. As an example user interface, a UILabel will be created and added to the view. Each view controller has an associated view property, and child views can be added with the addSubview method. To make the view stand out, the background of the view will be changed to black and the text color will be changed to white: class ViewController: UIViewController {   override func viewDidLoad() {     super.viewDidLoad()     view.backgroundColor = UIColor.blackColor()     let label = UILabel(frame:view.bounds)     label.textColor = UIColor.whiteColor()     label.textAlignment = .Center     label.text = "Welcome to Swift"       view.addSubview(label)   } } This creates a label, which is sized to the full size of the screen, with a white text color and a centered text alignment. When run, this displays Welcome to Swift on the screen. Typically, views will be implemented in their own class rather than being in-lined into the view controller. This allows the views to be reused in other controllers. When the screen is rotated, the label will be rotated off screen. Logic would need to be added in a real application to handle rotation changes in the view controller, such as willRotateToInterfaceOrientation, and to appropriately add rotations to the views using the transform property of the view. Usually, an interface builder file or storyboard would be used so that this is handled automatically. Swift classes, protocols, and enums Almost all Swift applications will be object oriented. Classes, such as Process from the CoreFoundation framework, and UIColor and UIImage from the UIKit framework, were used to demonstrate how classes can be used in applications. This section describes how to create classes, protocols, and enums in Swift. Classes in Swift A class is created in Swift using the class keyword, and braces are used to enclose the class body. The body can contain variables called properties, as well as functions called methods, which are collectively referred to as members. Instance members are unique to each instance, while static members are shared between all instances of that class. Classes are typically defined in a file named for the class; so a GitHubRepository class would typically be defined in a GitHubRepository.swift file. A new Swift file can be created by navigating to File | New | File… and selecting the Swift File option under iOS. Ensure that it is added to the Tests and UITests targets as well. Once created, implement the class as follows: class GitHubRepository {   var id:UInt64 = 0   var name:String = ""   func detailsURL() -> String {     return "https://api.github.com/repositories/(id)"   } } This class can be instantiated and used as follows: let repo = GitHubRepository() repo.id = 1 repo.name = "Grit" repo.detailsURL() // returns https://api.github.com/repositories/1 It is possible to create static members, which are the same for all instances of a class. In the GitHubRepository class, the api URL is likely to remain the same for all invocations, so it can be refactored into a static property: class GitHubRepository {   // does not work in Swift 1.0 or 1.1   static let api = "https://api.github.com"   …   class func detailsURL(id:String) -> String {     return "(api)/repositories/(id)"   } } Now, if the api URL needs to be changed (for example, to support mock testing or to support an in-house GitHub Enterprise server), there is a single place to change it. Before Swift 2, a class variables are not yet supported error message may be displayed. To use static variables in Swift prior to version 2, a different approach must be used. It is possible to define computed properties, which are not stored but are calculated on demand. These have a getter (also known as an accessor) and optionally a setter (also known as a mutator). The previous example can be rewritten as follows: class GitHubRepository {   class var api:String {     get {       return "https://api.github.com"     }   }   func detailsURL() -> String {     return "(GitHubRepository.api)/repositories/(id)"   } } Although this is logically a read-only constant (there is no associated set block), it is not possible to define the let constants with accessors. To refer to a class variable, use the type name—which in this case is GitHubRepository. When the GitHubRepository.api expression is evaluated, the body of the getter is called. Subclasses and testing in Swift A simple Swift class with no explicit parent is known as a base class. However, classes in Swift frequently inherit from another class by specifying a superclass after the class name. The syntax for this is class SubClass:SuperClass{...}. Tests in Swift are written using the XCTest framework, which is included by default in Xcode templates. This allows an application to have tests written and then executed in place to confirm that no bugs have been introduced. XCTest replaces the previous testing framework OCUnit. The XCTest framework has a base class called XCTestCase that all tests inherit from. Methods beginning with test (and that take no arguments) in the test case class are invoked automatically when the tests are run. Test code can indicate success or failure by calling the XCTAssert* functions, such as XCTAssertEquals and XCTAssertGreaterThan. Tests for the GitHubRepository class conventionally exist in a corresponding GitHubRepositoryTest class, which will be a subclass of XCTestCase. Create a new Swift file by navigating to File | New | File... and choosing a Swift File under the Source category for iOS. Ensure that the Tests and UITests targets are selected but the application target is not. It can be implemented as follows: import XCTest class GitHubRepositoryTest: XCTestCase {   func testRepository() {     let repo = GitHubRepository()     repo.id = 1     repo.name = "Grit"     XCTAssertEqual(       repo.detailsURL(),       "https://api.github.com/repositories/1",       "Repository details"     )   } } Make sure that the GitHubRepositoryTest class is added to the test targets. If not added when the file is created, it can be done by selecting the file and pressing Command + Option + 1 to show the File Inspector. The checkbox next to the test target should be selected. Tests should never be added to the main target. The GitHubRepository class should be added to both test targets: When the tests are run by pressing Command + U or by navigating to Product | Test, the results of the test will be displayed. Changing either the implementation or the expected test result will demonstrate whether the test is being executed correctly. Always check whether a failing test causes the build to fail; this will confirm that the test is actually being run. For example, in the GitHubRepositoryTest class, modify the URL to remove https from the front and check whether a test failure is shown. There is nothing more useless than a correctly implemented test that never runs. Protocols in Swift A protocol is similar to an interface in other languages; it is a named type that has method signatures but no method implementations. Classes can implement zero or more protocols; when they do, they are said to adopt or conform to the protocol. A protocol may have a number of methods that are either required (the default) or optional (marked with the optional keyword). Optional protocol methods are only supported when the protocol is marked with the @objc attribute. This declares that the class will be backed by an NSObject class for interoperability with Objective-C. Pure Swift protocols cannot have optional methods. The syntax to define a protocol looks similar to the following: protocol GitHubDetails {   func detailsURL() -> String   // protocol needs @objc if using optional protocols   // optional doNotNeedToImplement() } Protocols cannot have functions with default arguments. Protocols can be used with the struct, class, and enum types unless the @objc class attribute is used; in which case, they can only be used against Objective-C classes or enums. Classes conform to protocols by listing the protocol names after the class name, similar to a superclass. When a class has both a superclass and one or more protocols, the superclass must be listed first. class GitHubRepository: GitHubDetails {   func detailsURL() -> String {     // implementation as before   } } The GitHubDetails protocol can be used as a type in the same places as an existing Swift type, such as a variable type, method return type, or argument type. Protocols are widely used in Swift to allow callbacks from frameworks that would, otherwise, not know about specific callback handlers. If a superclass was required instead, then a single class cannot be used to implement multiple callbacks. Common protocols include UIApplicationDelegate, Printable, and Comparable. Enums in Swift The final concept to understand in Swift is enumeration, or enum for short. An enum is a closed set of values, such as North, East, South, and West, or Up, and Down. An enumeration is defined using the enum keyword, followed by a type name, and a block, which contains the case keywords followed by comma-separated values as follows: enum Suit {   case Clubs, Diamonds, Hearts // many on one line   case Spades // or each on separate lines } Unlike C, enumerated values do not have a specific type by default, so they cannot generally be converted to and from an integer value. Enumerations can be defined with raw values that allow conversion to and from integer values. Enum values are assigned to variables using the type name and the enum name: var suit:Suit = Suit.Clubs However, if the type of the expression is known, then the type prefix does not need to be explicitly specified; the following form is much more common in Swift code: var suit:Suit = .Clubs Raw values For the enum values that have specific meanings, it is possible to extend the enum from a different type, such as Int. These are known as raw values: enum Rank: Int {   case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten   case Jack, Queen, King, Ace } A raw value enum can be converted to and from its raw value with the rawValue property and the failable initializer Rank(rawValue:) as follows: Rank.Two.rawValue == 2 Rank(rawValue:14)! == .Ace The failable initializer returns an optional enum value, because the equivalent Rank may not exist. The expression Rank(rawValue:0) will return nil, for example. Associated values Enums can also have associated values, such as a value or case class in other languages. For example, a combination of a Suit and a Rank can be combined to form a Card: enum Card {   case Face(Rank, Suit)   case Joker } Instances can be created by passing values into an enum initializer: var aceOfSpades: Card = .Face(.Ace,.Spades) var twoOfHearts: Card = .Face(.Two,.Hearts) var theJoker: Card = .Joker The associated values of an enum instance cannot be extracted (as they can with properties of a struct), but the enum value can be accessed by pattern matching in a switch statement: var card = aceOfSpades // or theJoker or twoOfHearts ... switch card {   case .Face(let rank, let suit):     print("Got a face card (rank) of (suit)");   case .Joker:     print("Got the joker card") } The Swift compiler will require that the switch statement be exhaustive. As the enum only contains these two types, no default block is needed. If another enum value is added to Card in the future, the compiler will report an error in this switch statement. Creating a master-detail iOS application Having covered how classes, protocols, and enums are defined in Swift, a more complex master-detail application can be created. A master-detail application is a specific type of iOS application that initially presents a master table view, and when an individual element is selected, a secondary details view will show more information about the selected item. Using the Create a new Xcode project option from the welcome screen, or by navigating to File | New | Project… or by pressing Command + Shift + N, create a new project and select Master-Detail Application from the iOS Application category: In the subsequent dialog, enter appropriate values for the project, such as the name (MasterDetail), the organization identifier (typically based on the reverse DNS name), ensure that the Language dropdown reads Swift and that it is targeted for Universal devices: When the project is created, an Xcode window will open containing all the files that are created by the wizard itself, including the MasterDetail.app and MasterDetailTests.xctest products. The MasterDetail.app is a bundle that is executed by the simulator or a connected device, while the MasterDetailTests.xctest and MasterDetailsUITests.xctest products are used to execute unit tests for the application's code. The application can be launched by pressing the triangular play button on the top-left corner of Xcode or by pressing Command + R, which will run the application against the currently selected target. After a brief compile and build cycle, the iOS Simulator will open with a master page that contains an empty table, as shown in the following screenshot: The default MasterDetail application can be used to add items to the list by clicking on the add (+) button on the top-right corner of the screen. This will add a new timestamped entry to the list. When this item is clicked, the screen will switch to the details view, which, in this case, presents the time in the center of the screen: This kind of master-detail application is common in iOS applications for displaying a top-level list (such as a shopping list, a set of contacts, to-do notes, and so on) while allowing the user to tap to see the details. There are three main classes in the master-detail application: The AppDelegate class is defined in the AppDelegate.swift file, and it is responsible for starting the application and set up the initial state The MasterViewController class is defined in the MasterViewController.swift file, and it is used to manage the first (master) screen's content and interactions The DetailViewController class is defined in the DetailViewController.swift file, and it is used to manage the second (detail) screen's content In order to understand what the classes do in more detail, the next three sections will present each of them in turn. The code that is generated in this section was created from Xcode 7.0, so the templates might differ slightly if using a different version of Xcode. An exact copy of the corresponding code can be acquired from the Packt website or from this book's GitHub repository at https://github.com/alblue/com.packtpub.swift.essentials/. The AppDelegate class The AppDelegate class is the main entry point to the application. When a set of Swift source files are compiled, if the main.swift file exists, it is used as the entry point for the application by running that code. However, to simplify setting up an application for iOS, a @UIApplicationMain special attribute exists that will both synthesize the main method and set up the associated class as the application delegate. The AppDelegate class for iOS extends the UIResponder class, which is the parent of all the UI content on iOS. It also adopts two protocols, UIApplicationDelegate, and UISplitViewControllerDelegate, which are used to provide callbacks when certain events occur: @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate,    UISplitViewControllerDelegate {   var window: UIWindow?   ... } On OS X, the AppDelegate class will be a subclass of NSApplication and will adopt the NSApplicationDelegate protocol. The synthesized main function calls the UIApplicationMain method that reads the Info.plist file. If the UILaunchStoryboardName key exists and points to a suitable file (the LaunchScreen.xib interface file in this case), it will be shown as a splash screen before doing any further work. After the rest of the application has loaded, if the UIMainStoryboardFile key exists and points to a suitable file (the Main.storyboard file in this case), the storyboard is launched and the initial view controller is shown. The storyboard has references to the MasterViewController and DetailViewController classes. The window variable is assigned to the storyboard's window. The application:didFinishLaunchingWithOptions is called once the application has started. It is passed with a reference to the UIApplication instance and a dictionary of options that notifies how the application has been started: func application(  application: UIApplication,  didFinishLaunchingWithOptions launchOptions:   [NSObject: AnyObject]?) -> Bool {   // Override point for customization after application launch.   ... } In the sample MasterDetail application, the application:didFinishLaunchingWithOptions method acquires a reference to the splitViewController from the explicitly unwrapped optional window, and the AppDelegate is set as its delegate: let splitViewController =  self.window!.rootViewController as! UISplitViewController splitViewController.delegate = self The … as! UISplitViewController syntax performs a type cast so that the generic rootViewController can be assigned to the more specific type; in this case, UISplitViewController. An alternative version as? provides a runtime checked cast, and it returns an optional value that either contains the value with the correctly casted type or nil otherwise. The difference with as! is a runtime error will occur if the item is not of the correct type. Finally, a navigationController is acquired from the splitViewController, which stores an array of viewControllers. This allows the DetailView to display a button on the left-hand side to expand the details view if necessary: let navigationController = splitViewController.viewController  [splitViewController.viewControllers.count-1]  as! UINavigationController navigationController.topViewController  .navigationItem.leftBarButtonItem =  splitViewController.displayModeButtonItem() The only difference this makes is when running on a wide-screen device, such as an iPhone 6 Plus or an iPad, where the views are displayed side-by-side in landscape mode. This is a new feature in iOS 8 applications. Otherwise, when the device is in portrait mode, it will be rendered as a standard back button: The method concludes with return true to let the OS know that the application has opened successfully. The MasterViewController class The MasterViewController class is responsible for coordinating the data that is shown on the first screen (when the device is in portrait orientation) or the left-half of the screen (when a large device is in landscape orientation). This is rendered with a UITableView, and data is coordinated through the parent UITableViewController class: class MasterViewController: UITableViewController {   var detailViewcontroller: DetailViewController? = nil   var objects = [AnyObject]()   override func viewDidLoad() {…}   func insertNewObject(sender: AnyObject) {…}   … } The viewDidLoad method is used to set up or initialize the view after it has loaded. In this case, a UIBarButtonItem is created so that the user can add new entries to the table. The UIBarButtonItem takes a @selector in Objective-C, and in Swift is treated as a string literal convertible (so that "insertNewObject:" will result in a call to the insertNewObject method). Once created, the button is added to the navigation on the right-hand side, using the standard .Add type which will be rendered as a + sign on the screen: override func viewDidLoad() {   super.viewDidLoad()   self.navigationItem.leftBarButtonItem = self.editButtonItem()   let addButton = UIBarButtonItem(     barButtonSystemItem: .Add, target: self,     action: "insertNewObject:")   self.navigationItem.rightBarButtonItem = addButton   if let split = self.splitViewController {     let controllers = split.viewControllers     self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController } The objects are NSDate values, and are stored inside the class as an Array of AnyObject elements. The insertNewObject method is called when the + button is pressed, and it creates a new NSDate instance which is then inserted into the array. The sender event is passed as an argument of the AnyObject type, which will be a reference to the UIBarButtonItem (although it is not needed or used here): func insertNewObject(sender: AnyObject) {   objects.insertObject(NSDate.date(), atIndex: 0)   let indexPath = NSIndexPath(forRow: 0, inSection: 0)   self.tableView.insertRowsAtIndexPaths(    [indexPath], withRowAnimation: .Automatic) } The UIBarButtonItem class was created before blocks were available on iOS devices, so it uses the older Objective-C @selector mechanism. A future release of iOS may provide an alternative that takes a block, in which case Swift functions can be passed instead. The parent class contains a reference to the tableView, which is automatically created by the storyboard. When an item is inserted, the tableView is notified that a new object is available. Standard UITableViewController methods are used to access the data from the array: override func numberOfSectionsInTableView(  tableView: UITableView) -> Int {   return 1 } override func tableView(tableView: UITableView,  numberOfRowsInSection section: Int) -> Int {   return objects.count } override func tableView(tableView: UITableView,  cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{   let cell = tableView.dequeueReusableCellWithIdentifier(    "Cell", forIndexPath: indexPath)   let object = objects[indexPath.row] as! NSDate   cell.textLabel!.text = object.description   return cell } override func tableView(tableView: UITableView,  canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {   return true } The numberOfSectionsInTableView function returns 1 in this case, but a tableView can have multiple sections; for example, to permit a contacts application having a different section for A, B, C through Z. The numberOfRowsInSection method returns the number of elements in each section; in this case, as there is only one section, the number of objects in the array. The reason why each method is called tableView and takes a tableView argument is a result of the Objective-C heritage of UIKit. The Objective-C convention combined the method name as the first named argument, so the original method was [delegate tableView:UITableView, numberOfRowsInSection:NSInteger]. As a result, the name of the first argument is reused as the name of the method in Swift. The cellForRowAtIndexPath method is expected to return UITableViewCell for an object. In this case, a cell is acquired from the tableView using the dequeueReusableCellWithIdentifier method (which caches cells as they go off screen to save object instantiation), and then the textLabel is populated with the object's description (which is a String representation of the object; in this case, the date). This is enough to display elements in the table, but in order to permit editing (or just removal, as in the sample application), there are some additional protocol methods that are required: override func tableView(tableView: UITableView,  canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {   return true } override func tableView(tableView: UITableView,  commitEditingStyle editingStyle: UITableViewCellEditingStyle,  forRowAtIndexPath indexPath: NSIndexPath) {   if editingStyle == .Delete {     objects.removeObjectAtIndex(indexPath.row)     tableView.deleteRowsAtIndexPaths([indexPath],      withRowAnimation: .Fade)   } } The canEditRowAtIndexPath method returns true if the row is editable; if all the rows can be edited, then this will return true for all the values. The commitEditingStyle method takes a table, a path, and a style, which is an enumeration that indicates which operation occurred. In this case, UITableViewCellEditingStyle.Delete is passed in order to delete the item from both the underlying object array and also from the tableView. (The enumeration can be abbreviated to .Delete because the type of editingStyle is known to be UITableViewCellEditingStyle.) The DetailViewController class The detail view is shown when an element is selected in the MasterViewController. The transition is managed by the storyboard controller; the views are connected with a segue (pronounced seg-way; the product of the same name based it on the word segue which is derived from the Italian word for follows). To pass the selected item between controllers, a property exists in the DetailViewController class called detailItem. When the value is changed, additional code is run, which is implemented in a didSet property notification: class DetailViewController: UIViewController {   var detailItem: AnyObject? {     didSet {       self.configureView()     }   }   … } When DetailViewController has the detailItem set, the configureView method will be invoked. The didSet body is run after the value has been changed, but before the setter returns to the caller. This is triggered by the segue in the MasterViewController: class MasterViewController: UIViewController {   …   override func prepareForSegue(    segue: UIStoryboardSegue, sender: AnyObject?) {     super.prepareForSegue(segue, sender: sender)     if segue.identifier == "showDetail" {       if let indexPath =        self.tableView.indexPathForSelectedRow() {         let object = objects[indexPath.row] as! NSDate         let controller = (segue.destinationViewController          as! UINavigationController)          .topViewController as! DetailViewController         controller.detailItem = object         controller.navigationItem.leftBarButtonItem =          self.splitViewController?.displayModeButtonItem()         controller.navigationItem.leftItemsSupplementBackButton =          true       }     }   } } The prepareForSegue method is called when the user selects an item in the table. In this case, it grabs the selected row index from the table and uses this to acquire the selected date object. The navigation controller hierarchy is searched to acquire the DetailViewController, and once this has been obtained, the selected value is set with controller.detailItem = object, which triggers the update. The label is ultimately displayed in the DetailViewController through the configureView method, which stamps the description of the object onto the label in the center: class DetailViewController {   ...   @IBOutlet weak var detailDescriptionLabel: UILabel!   function configureView() {     if let detail: AnyObject = self.detailItem {       if let label = self.detailDescriptionLabel {         label.text = detail.description       }     }   } } The configureView method is called both when the detailItem is changed and when the view is loaded for the first time. If the detailItem has not been set, then this has no effect. The implementation introduces some new concepts, which are worth highlighting: The @IBOutlet attribute indicates that the property will be exposed in interface builder and can be wired up to the object instance. The weak attribute indicates that the property will not store a strong reference to the object; in other words, the detail view will not own the object but merely reference it. Generally, all @IBOutlet references should be declared as weak to avoid cyclic dependency references. The type is defined as UILabel! which is an implicitly unwrapped optional. When accessed, it performs an explicit unwrapping of the optional value; otherwise the @IBOutlet will be wired up as a UILabel? optional type. Implicitly unwrapped optional types are used when the variable is known to never be nil at runtime, which is usually the case for the @IBOutlet references. Generally, all @IBOutlet references should be implicitly unwrapped optionals. Summary In this article we saw two sample iOS applications; one in which the UI was created programmatically, and another in which the UI was loaded from a storyboard. Together with an overview of classes, protocols, and enums, and an explanation of how iOS applications start, this article gives a springboard to understand the Xcode templates that are frequently used to start new projects. To learn more about Swift 2, you can refer the following books published by Packt Publishing (https://www.packtpub.com/): Swift 2 Blueprints (https://www.packtpub.com/application-development/swift-2-blueprints) Mastering Swift 2 (https://www.packtpub.com/application-development/mastering-swift-2) Swift 2 Design Patterns (https://www.packtpub.com/application-development/swift-2-design-patterns) Resources for Article:   Further resources on this subject: Your First Swift App [article] C-Quence – A Memory Game [article] Exploring Swift [article]
Read more
  • 0
  • 0
  • 8631

article-image-new-ipad-features-ios-6
Packt
20 Feb 2013
2 min read
Save for later

New iPad Features in iOS 6

Packt
20 Feb 2013
2 min read
(For more resources related to this topic, see here.) New iPad features and native applications We're going to identify some of the applications that come built-in to the new iPad. The applications designed by Apple for the iPad are Safari, Mail, Photos, FaceTime, Maps, Siri, Newsstand, Messages, Calendar, Reminders, Contacts, App Store, iTunes, Music, Videos, Notes, Camera, Photo Booth, Clock, Game Center, and Settings. Let's get started by exploring these applications. Getting ready Locate the Mail, Photos, App Store, iTunes, Music, and Settings apps For details on each app, visit http://www.apple.com/ipad/built-in-apps/ How to do it... These apps form the base of the iPad and by themselves can satisfy most of our media and communication needs. We'll delve deeper into each of the following apps in the upcoming recipes. Mail Photos App Store iTunes and Music Settings How it works... The applications can work together to provide a unifying experience. From the Photos app, we are able to share photos via the Mail application. Purchasing music in iTunes will allow us playback in our Music app. Ubiquity is what makes this device and its apps so useful. Summary This article gave us a brief overview of the application that illustrate the new iPad's features. Resources for Article : Further resources on this subject: Build iPhone, Android and iPad Applications using jQTouch [Article] Getting Started on UDK with iOS [Article] Interface Designing for Games in iOS [Article]
Read more
  • 0
  • 0
  • 8593

article-image-add-a-twitter-sign-in-to-your-ios-app-with-twitterkit
Doron Katz
15 Mar 2015
5 min read
Save for later

Add a Twitter Sign In To Your iOS App with TwitterKit

Doron Katz
15 Mar 2015
5 min read
What is TwitterKit & Digits? In this post we take a look at Twitter’s new Sign-in API, TwitterKit and Digits, bundled as part of it’s new Fabric suite of tools, announced by Twitter earlier this year, as well as providing you with two quick snippets on on how to integrate Twitter’s sign-in mechanism into your iOS app. Facebook, and to a lesser-extent Google, have for a while dominated the single sign-on paradigm, through their SDK or Accounts.framework on iOS, to encourage developers to provide a consolidated form of login for their users. Twitter has decided to finally get on the band-wagon and work toward improving its brand through increasing sign-on participation, and providing a concise way for users to log-in to their favorite apps without needing to remember individual passwords. By providing a Login via Twitter button, developers will gain the user’s Twitter identity, and subsequently their associated twitter tweets and associations. That is, once the twitter account is identified, the app can engage followers of that account (friends), or to access the user’s history of tweets, to data-mind for a specific keyword or hashtag. In addition to offering a single sign-on, Twitter is also offering Digits, the ability for users to sign-on anonymously using one’s phone number, synonymous with Facebook’s new Anonymous Login API.   The benefits of Digit The rationale behind Digits is to provide users with the option of trusting the app or website and providing their Twitter identification in order to log-in. Another option for the more hesitant ones wanting to protect their social graph history, is to only provide a unique number, which happens to be a mobile number, as a means of identification and authentication. Another benefit for users is that logging in is dead-simple, and rather than having to go through a deterring form of identification questions, you just ask them for their number, from which they will get an authentication confirmation SMS, allowing them to log-in. With a brief introduction to TwitterKit and Digits, let’s show you how simple it is to implement each one. Logging in with TwitterKit Twitter wanted to make implementing its authentication mechanism a more simpler and attractive process for developers, which they did. By using the SDK as part of Twitter’s Fabric suite, you will already get your Twitter app set-up and ready, registered for use with the company’s SDK. TwitterKit aims to leverage the existing Twitter account on the iOS, using the Accounts.framework, which is the preferred and most rudimentary approach, with a fallback to using the OAuth mechanism. The easiest way to implement Twitter authentication is through the generated button, TWTRLogInButton, as we will demonstrate using iOS’Swift language. let authenticationButton = TWTRLogInButton(logInCompletion: { (session, error) in if (session != nil) { //We signed in, storing session in session object. } else { //we get an error, accessible from error object } }) It’s quite simple, leaving you with a TWTRLoginButton button subclass, that users can add to your view hierarchy and have users interact with. Logging in with Digits Having created a login button using TwitterKit, we will now create the same feature using Digits. The simplicity of implementation is maintained with Digits, with the simplest process once again to create a pre-configured button, DGTAuthenticateButton: let authenticationButton = TWTRLogInButton(logInCompletion: { (session, error) in if (session != nil) { //We signed in, storing session in session object. } else { //we get an error, accessible from error object } }) Summary Implementing TwitterKit and Digits are both quite straight forward in iOS, with different intentions. Whereas TwitterKit allows you to have full-access to the authenticated user’s social history, the latter allows for a more abbreviated, privacy-protected approach to authenticating. If at some stage the user decides to trust the app and feels more comfortable providing full access of her or his social history, you can defer catering to that till later in the app usage. The complete iOS reference for TwitterKit and Digits can be found by clicking here. The popularity and uptake of TwitterKit remains to be seen, but as an extra option for developers, when adding Facebook and Google+ login, users will have the option to pick their most trusted social media tool as their choice of authentication. Providing an anonymous mode of login also falls in line with the more privacy-conscious world, and Digits certainly provides a seamless way of implementing, and impressively straight-forward way for users to authenticate using their phone number. We have briefly demonstrated how to interact with Twitter’s SDK using iOS and Swift, but there is also an Android SDK version, with a Web version in the pipeline very soon, according to Twitter. This is certainly worth exploring, along with the rest of the tools offered in the Fabric suite, including analytics and beta-distribution tools, and more. About the author Doron Katz is an established Mobile Project Manager, Architect and Developer, and a pupil of the methodology of Agile Project Management,such as applying Kanban principles. Doron also believes in BehaviourDriven Development (BDD), anticipating user interaction prior to design, that is. Doron is also heavily involved in various technical user groups, such as CocoaHeads Sydney, and Adobe user Group.
Read more
  • 0
  • 0
  • 8469

article-image-physics-uikit-dynamics
Packt
14 May 2014
8 min read
Save for later

Physics with UIKit Dynamics

Packt
14 May 2014
8 min read
(For more resources related to this topic, see here.) Motion and physics in UIKit With the introduction of iOS 7, Apple completely removed the skeuomorphic design that has been used since the introduction of the iPhone and iOS. In its place is a new and refreshing flat design that features muted gradients and minimal interface elements. Apple has strongly encouraged developers to move away from a skeuomorphic and real-world-based design in favor of these flat designs. Although we are guided away from a real-world look, Apple also strongly encourages that your user interface have a real-world feel. Some may think this is a contradiction; however, the goal is to give users a deeper connection to the user interface. UI elements that respond to touch, gestures, and changes in orientation are examples of how to apply this new design paradigm. In order to help assist in this new design approach, Apple has introduced two very nifty APIs, UIKit Dynamics and Motion Effects. UIKit Dynamics To put it simply, iOS 7 has a fully featured physics engine built into UIKit. You can manipulate specific properties to provide a more real-world feel to your interface. This includes gravity, springs, elasticity, bounce, and force to name a few. Each interface item will contain its own properties and the dynamic engine will abide by these properties. Motion effects One of the coolest features of iOS 7 on our devices is the parallax effect found on the home screen. Tilting the device in any direction will pan the background image to emphasize depth. Using motion effects, we can monitor the data supplied by the device's accelerometer to adjust our interface based on movement and orientation. By combining these two features, you can create great looking interfaces with a realistic feel that brings it to life. To demonstrate UIKit Dynamics, we will be adding some code to our FoodDetailViewController.m file to create some nice effects and animations. Adding gravity Open FoodDetailViewController.m and add the following instance variables to the view controller: UIDynamicAnimator* animator; UIGravityBehavior* gravity; Scroll to viewDidLoad and add the following code to the bottom of the method: animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; gravity = [[UIGravityBehavior alloc] initWithItems:@[self.foodImageView]]; [animator addBehavior:gravity]; Run the application, open the My Foods view, select a food item from the table view, and watch what happens. The food image should start to accelerate towards the bottom of the screen until it eventually falls off the screen, as shown in the following set of screenshots: Let's go over the code, specifically the two new classes that were just introduced, UIDynamicAnimator and UIGravityBehavior. UIDynamicAnimator This is the core component of UIKit Dynamics. It is safe to say that the dynamic animator is the physics engine itself wrapped in a convenient and easy-to-use class. The animator will do nothing on its own, but instead keep track of behaviors assigned to it. Each behavior will interact inside of this physics engine. UIGravityBehavior Behaviors are the core compositions of UIKit Dynamics animation. These behaviors all define individual responses to the physics environment. This particular behavior mimics the effects of gravity by applying force. Each behavior is associated with a view (or views) when created. Because you explicitly define this property, you can control which views will perform the behavior. Behavior properties Almost all behaviors have multiple properties that can be adjusted to the desired effect. A good example is the gravity behavior. We can adjust its angle and magnitude. Add the following code before adding the behavior to the animator: gravity.magnitude = 0.1f; Run the application and test it to see what happens. The picture view will start to fall; however, this time it will be at a much slower rate. Replace the preceding code line with the following line: gravity.magnitude = 10.0f; Run the application, and this time you will notice that the image falls much faster. Feel free to play with these properties and get a feel for each value. Creating boundaries When dealing with gravity, UIKit Dynamics does not conform to the boundaries of the screen. Although it is not visible, the food image continues to fall after it has passed the edge of the screen. It will continue to fall unless we set boundaries that will contain the image view. At the top of the file, create another instance variable: UICollisionBehavior *collision; Now in our viewDidLoad method, add the following code below our gravity code: collision = [[UICollisionBehavior alloc] initWithItems:@[self.foodImageView]]; collision.translatesReferenceBoundsIntoBoundary = YES; [animator addBehavior:collision]; Here we are creating an instance of a new class (which is a behavior), UICollisionBehavior. Just like our gravity behavior, we associate this behavior with our food image view. Rather than explicitly defining the coordinates for the boundary, we use the convenient translatesReferenceBoundsIntoBoundary property on our collision behavior. By setting this property to yes, the boundary will be defined by the bounds of the reference view that we set when allocating our UIDynamics animator. Because the reference view is self.view, the boundary is now the visible space of our view. Run the application and watch how the image will fall, but stop once it reaches the bottom of the screen, as shown in the following screenshot: Collisions With our image view responding to gravity and our screen bounds we can start detecting collisions. You may have noticed that when the image view is falling, it falls right through our two labels below it. This is because UIKit Dynamics will only respond to UIView elements that have been assigned behaviors. Each behavior can be assigned to multiple objects, and each object can have multiple behaviors. Because our labels have no behaviors associated with them, the UIKit Dynamics physics engine simply ignores it. Let's make the food image view collide with the date label. To do this, we simply need to add the label to the collision behavior allocation call. Here is what the new code looks like: collision = [[UICollisionBehavior alloc] initWithItems:@[self.foodImageView, self.foodDateLabel]]; As you can see, all we have done is add self.foodDateLabel to the initWithItems array property. As mentioned before, any single behavior can be associated with multiple items. Run your code and see what happens. When the image falls, it hits the date label but continues to fall, pushing the date label with it. Because we didn't associate the gravity behavior with the label, it does not fall immediately. Although it does not respond to gravity, the label will still be moved because it is a physics object after all. This approach is not ideal, so let's use another awesome feature of UIKit Dynamics, invisible boundaries. Creating invisible boundaries We are going to take a slightly different approach to this problem. Our label is only a point of reference for where we want to add a boundary that will stop our food image view. Because of this, the label does not need to be associated with any UIKit Dynamic behaviors. Remove self.foodDateLabel from the following code: collision = [[UICollisionBehavior alloc] initWithItems:@[self.foodImageView, self.foodDateLabel]]; Instead, add the following code to the bottom of viewDidLoad but before we add our collision behavior to the animator: // Add a boundary to the top edge CGPoint topEdge = CGPointMake(self.foodDateLabel.frame.origin.x + self.foodDateLabel.frame.size.width, self.foodDateLabel.frame.origin.y); [collision addBoundaryWithIdentifier:@"barrier" fromPoint:self.foodDateLabel.frame.origin toPoint:topEdge]; Here we add a boundary to the collision behavior and pass some parameters. First we define an identifier, which we will use later, and then we pass the food date label's origin as the fromPoint property. The toPoint property is set to the CGPoint we created using the food date label's frame. Go ahead and run the application, and you will see that the food image will now stop at the invisible boundary we defined. The label is still visible to the user, but the dynamic animator ignores it. Instead the animator sees the barrier we defined and responds accordingly, even though the barrier is invisible to the user. Here is a side-by-side comparison of the before and after: Dynamic items When using UIKit Dynamics, it is important to understand what UIKit Dynamics items are. Rather than referencing dynamics as views, they are referenced as items, which adhere to the UIDynamicItem protocol. This protocol defines the center, transform, and bounds of any object that adheres to this protocol. UIView is the most common class that adheres to the UIDynamicItem protocol. Another example of a class that conforms to this protocol is the UICollectionViewLayoutAttributes class. Summary In this article, we covered some basics of how UIKit Dynamics manages your application's behaviors, that enables us to create some really unique interface effects. Resources for Article: Further resources on this subject: Linking OpenCV to an iOS project [article] Unity iOS Essentials: Flyby Background [article] New iPad Features in iOS 6 [article]
Read more
  • 0
  • 0
  • 8384

Packt
23 Apr 2014
7 min read
Save for later

User Interactivity – Mini Golf

Packt
23 Apr 2014
7 min read
(For more resources related to this topic, see here.) Using user input and touch events A touch event occurs each time a user touches the screen, drags, or releases the screen, and also during an interruption. Touch events begin with a user touching the screen. The touches are all handled by the UIResponder class, which then causes a UIEvent object to be generated, which then passes your code to a UITouch object for each finger touching the screen. For most of the code you work on, you will be concerned about the basic information. Where did the user start to touch the screen? Did they drag their finger across the screen? And, where did they let go? You will also want to know if the touch event got interrupted or canceled by another event. All of these situations can be handled in your view controller code using the following four methods (You can probably figure out what each one does.): -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event These methods are structured pretty simply, and we will show you how to implement these a little later in the article. When a touch event occurs on an object, let's say a button, that object will maintain the touch event until it has ended. So, if you touch a button and drag your finger outside the button, the touch-ended event is sent to the button as a touch up outside event. This is very important to know when you are setting up touches for your code. If you have a set of touch events associated with your background and another set associated with a button in the foreground, you need to understand that if touchesBegan begins on the button and touchesEnded ends on the background, touchesEnded is still passed to your button. In this article, we will be creating a simple Mini Golf game. We start with the ball in a standard start position on the screen. The user can touch anywhere on the screen and drag their finger in any direction and release. The ball will move in the direction the player dragged their finger, and the longer the distance from their original position, the more powerful the shot will be. In the Mini Golf game, we put the touch events on the background and not the ball for one simple reason. When the user's ball stops close to the edge of the screen, we still want them to be able to drag a long distance for more power. Using gestures in iOS apps There are special types of touch events known as gestures. Gestures are used all over in iOS apps, but most notable is their use in maps. The simplest gesture would be tap, which is used for selecting items; however, gestures such as pinch and rotate are used for scaling and, well, rotating. The most common gestures have been put together in the Gesture Recognizer classes from Apple, and they work on all iOS devices. These gestures are tap, pinch, rotate, swipe, pan, and long press. You will see all of the following items listed in your Object Library: Tap: This is an simple touch and release on the screen. A tap may also include multiple taps. Pinch: This is a gesture involving a two-finger touch and dragging of your fingers together or apart. Rotate: This is a gesture involving a two finger-touch and rotation of your fingers in a circle. Swipe: This gesture involves holding a touch down and then dragging to a release point. Pan: This gesture involves holding a touch and dragging. A pan does not have an end point like the swipe but instead recognizes direction. Long press: This gesture involves a simple touch and hold for a prespecified minimum amount of time. The following screenshot displays the Object Library: Let's get started on our new game as we show you how to integrate a gesture into your game: We'll start by making our standard Single View Application project. Let's call this one MiniGolf and save it to a new directory, as shown in the following screenshot: Once your project has been created, select it and uncheck Landscape Left and Landscape Right in your Deployment Info. Create a new Objective-C class file for our game view controller with a subclass of UIViewController, which we will call MiniGolfViewController so that we don't confuse it with our other game view controllers: Next, you will need to drag it into the Resources folder for the Mini Golf game: Select your Main.storyboard, and let's get our initial menu set up. Drag in a new View Controller object from your Objects Library. We are only going to be working with two screens for this game. For the new View Controller object, let's set the custom class to your new MiniGolfViewController: Let's add in a background and a button to segue into our new Mini Golf View Controller scene. Drag out an Image View object from our Object Library and set it to full screen. Drag out a Button object and name it Play Game. Press control, click on the Play Game button, and drag over to the Mini Golf View Controller scene to create a modal segue, as shown in the next screenshot. We wouldn't normally do this with a game, but let's use gestures to create a segue from the main menu to start the game. In the ViewController.m file, add in your unwind code: - (IBAction)unwindToThisView:(UIStoryboardSegue *)unwindSegue { } In your ViewController.h file, add in the corresponding action declaration: - (IBAction)unwindToThisView:(UIStoryboardSegue *)unwindSegue; In the Mini Golf View Controller, let's drag out an Image View object, set it to full screen, and set the image to gameBackground.png. Drag out a Button object and call it Exit Game and a Label object and set Strokes to 0 in the text area. It should look similar to the following screenshot: Press control and click-and-drag your Exit Game button to the Exit unwind segue button, as shown in the following screenshot: If you are planning on running this game in multiple screen sizes, you should pin your images and buttons in place. If you are just running your code in the iPhone 4 simulator, you should be fine. That should just about do it for the usual prep work. Now, let's get into some gestures. If you run your game right now, you should be able to go into your game area and exit back out. But what if we wanted to set it up so that when you touch the screen and swipe right, you would use a different segue to enter the gameplay area? The actions performed on the gestures are as follows: Select your view and drag out Swipe Gesture Recognizer from your Objects Library onto your view: Press control and drag your Swipe Gesture Recognizer to your Mini Golf View Controller just like you did with your Play Game button. Choose a modal segue and you are done. For each of the different types of gestures that are offered in the Object Library, there are unique settings in the attributes inspector. For the swipe gesture, you can choose the swipe direction and the number of touches required to run. For example, you could set up a two-finger left swipe just by changing a few settings, as shown in the following screenshot: You could just as easily press control and click-and-drag from your Swipe Gesture Recognizer to your header file to add IBAction associated with your swipe; this way, you can control what happens when you swipe. You will need to set Type to UISwipeGestureRecognizer: Once you have done this, a new IBAction function will be added to both your header file and your implementation file: - (IBAction)SwipeDetected:(UISwipeGestureRecognizer *)sender; and - (IBAction)SwipeDetected:(UISwipeGestureRecognizer *)sender { //Code for when a user swipes } This works the same way for each of the gestures in the Object Library.
Read more
  • 0
  • 0
  • 8084
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-flappy-swift
Packt
16 Jun 2015
15 min read
Save for later

Flappy Swift

Packt
16 Jun 2015
15 min read
Let's start using the first framework by implementing a nice clone of Flappy Bird with the help of this article by Giordano Scalzo, the author of Swift by Example. (For more resources related to this topic, see here.) The app is… Only someone who has been living under a rock for the past two years may not have heard of Flappy Bird, but to be sure that everybody understands the game, let's go through a brief introduction. Flappy Bird is a simple, but addictive, game where the player controls a bird that must fly between a series of pipes. Gravity pulls the bird down, but by touching the screen, the player can make the bird flap and move towards the sky, driving the bird through a gap in a couple of pipes. The goal is to pass through as many pipes as possible. Our implementation will be a high-fidelity tribute to the original game, with the same simplicity and difficulty level. The app will consist of only two screens—a clean menu screen and the game itself—as shown in the following screenshot:   Building the skeleton of the app Let's start implementing the skeleton of our game using the SpriteKit game template. Creating the project For implementing a SpriteKit game, Xcode provides a convenient template, which prepares a project with all the useful settings: Go to New| Project and select the Game template, as shown in this screenshot: In the following screen, after filling in all the fields, pay attention and select SpriteKit under Game Technology, like this: By running the app and touching the screen, you will be delighted by the cute, rotating airplanes! Implementing the menu First of all, let's add CocoaPods; write the following code in the Podfile: use_frameworks!   target 'FlappySwift' do pod 'Cartography', '~> 0.5' pod 'HTPressableButton', '~> 1.3' end Then install CocoaPods by running the pod install command. As usual, we are going to implement the UI without using Interface Builder and the storyboards. Go to AppDelegate and add these lines to create the main ViewController:    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {        let viewController = MenuViewController()               let mainWindow = UIWindow(frame: UIScreen.mainScreen().bounds)        mainWindow.backgroundColor = UIColor.whiteColor()       mainWindow.rootViewController = viewController        mainWindow.makeKeyAndVisible()        window = mainWindow          return true    } The MenuViewController, as the name suggests, implements a nice menu to choose between the game and the Game Center: import UIKit import HTPressableButton import Cartography   class MenuViewController: UIViewController {    private let playButton = HTPressableButton(frame: CGRectMake(0, 0, 260, 50), buttonStyle: .Rect)    private let gameCenterButton = HTPressableButton(frame: CGRectMake(0, 0, 260, 50), buttonStyle: .Rect)      override func viewDidLoad() {        super.viewDidLoad()        setup()        layoutView()        style()        render()    } } As you can see, we are using the usual structure. Just for the sake of making the UI prettier, we are using HTPressableButtons instead of the default buttons. Despite the fact that we are using AutoLayout, the implementation of this custom button requires that we instantiate the button by passing a frame to it: // MARK: Setup private extension MenuViewController{    func setup(){        playButton.addTarget(self, action: "onPlayPressed:", forControlEvents: .TouchUpInside)        view.addSubview(playButton)        gameCenterButton.addTarget(self, action: "onGameCenterPressed:", forControlEvents: .TouchUpInside)        view.addSubview(gameCenterButton)    }       @objc func onPlayPressed(sender: UIButton) {        let vc = GameViewController()        vc.modalTransitionStyle = .CrossDissolve        presentViewController(vc, animated: true, completion: nil)    }       @objc func onGameCenterPressed(sender: UIButton) {        println("onGameCenterPressed")    }   } The only thing to note is that, because we are setting the function to be called when the button is pressed using the addTarget() function, we must prefix the designed methods using @objc. Otherwise, it will be impossible for the Objective-C runtime to find the correct method when the button is pressed. This is because they are implemented in a private extension; of course, you can set the extension as internal or public and you won't need to prepend @objc to the functions: // MARK: Layout extension MenuViewController{    func layoutView() {        layout(playButton) { view in             view.bottom == view.superview!.centerY - 60            view.centerX == view.superview!.centerX            view.height == 80            view.width == view.superview!.width - 40        }        layout(gameCenterButton) { view in            view.bottom == view.superview!.centerY + 60            view.centerX == view.superview!.centerX            view.height == 80            view.width == view.superview!.width - 40        }    } } The layout functions simply put the two buttons in the correct places on the screen: // MARK: Style private extension MenuViewController{    func style(){        playButton.buttonColor = UIColor.ht_grapeFruitColor()        playButton.shadowColor = UIColor.ht_grapeFruitDarkColor()        gameCenterButton.buttonColor = UIColor.ht_aquaColor()        gameCenterButton.shadowColor = UIColor.ht_aquaDarkColor()    } }   // MARK: Render private extension MenuViewController{    func render(){        playButton.setTitle("Play", forState: .Normal)        gameCenterButton.setTitle("Game Center", forState: .Normal)    } } Finally, we set the colors and text for the titles of the buttons. The following screenshot shows the complete menu: You will notice that on pressing Play, the app crashes. This is because the template is using the view defined in storyboard, and we are directly using the controllers. Let's change the code in GameViewController: class GameViewController: UIViewController {    private let skView = SKView()      override func viewDidLoad() {        super.viewDidLoad()        skView.frame = view.bounds        view.addSubview(skView)        if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {            scene.size = skView.frame.size            skView.showsFPS = true            skView.showsNodeCount = true            skView.ignoresSiblingOrder = true            scene.scaleMode = .AspectFill            skView.presentScene(scene)        }    } } We are basically creating the SKView programmatically, and setting its size just as we did for the main view's size. If the app is run now, everything will work fine. You can find the code for this version at https://github.com/gscalzo/FlappySwift/tree/the_menu_is_ready. A stage for a bird Let's kick-start the game by implementing the background, which is not as straightforward as it might sound. SpriteKit in a nutshell SpriteKit is a powerful, but easy-to-use, game framework introduced in iOS 7. It basically provides the infrastructure to move images onto the screen and interact with them. It also provides a physics engine (based on Box2D), a particles engine, and basic sound playback support, making it particularly suitable for casual games. The content of the game is drawn inside an SKView, which is a particular kind of UIView, so it can be placed inside a normal hierarchy of UIViews. The content of the game is organized into scenes, represented by subclasses of SKScene. Different parts of the game, such as the menu, levels, and so on, must be implemented in different SKScenes. You can consider an SK in SpriteKit as an equivalent of the UIViewController. Inside an SKScene, the elements of the game are grouped in the SKNode's tree which tells the SKScene how to render the components. An SKNode can be either a drawable node, such as SKSpriteNode or SKShapeNode; or something to be applied to the subtree of its descendants, such as SKEffectNode or SKCropNode. Note that SKScene is an SKNode itself. Nodes are animated using SKAction. An SKAction is a change that must be applied to a node, such as a move to a particular position, a change of scaling, or a change in the way the node appears. The actions can be grouped together to create actions that run in parallel, or wait for the end of a previous action. Finally, we can define physics-based relations between objects, defining mass, gravity, and how the nodes interact with each other. That said, the best way to understand and learn SpriteKit is by starting to play with it. So, without further ado, let's move on to the implementation of our tiny game. In this way, you'll get a complete understanding of the most important features of SpriteKit. Explaining the code In the previous section, we implemented the menu view, leaving the code similar to what was created by the template. With basic knowledge of SpriteKit, you can now start understanding the code: class GameViewController: UIViewController {    private let skView = SKView()      override func viewDidLoad() {        super.viewDidLoad()        skView.frame = view.bounds        view.addSubview(skView)        if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {            scene.size = skView.frame.size            skView.showsFPS = true            skView.showsNodeCount = true            skView.ignoresSiblingOrder = true            scene.scaleMode = .AspectFill            skView.presentScene(scene)        }    } } This is the UIViewController that starts the game; it creates an SKView to present the full screen. Then it instantiates the scene from GameScene.sks, which can be considered the equivalent of a Storyboard. Next, it enables some debug information before presenting the scene. It's now clear that we must implement the game inside the GameScene class. Simulating a three-dimensional world using parallax To simulate the depth of the in-game world, we are going to use the technique of parallax scrolling, a really popular method wherein the farther images on the game screen move slower than the closer images. In our case, we have three different levels, and we'll use three different speeds: Before implementing the scrolling background, we must import the images into our project, remembering to set each image as 2x in the assets. The assets can be downloaded from https://github.com/gscalzo/FlappySwift/blob/master/assets.zip?raw=true. The GameScene class basically sets up the background levels: import SpriteKit   class GameScene: SKScene {    private var screenNode: SKSpriteNode!    private var actors: [Startable]!      override func didMoveToView(view: SKView) {        screenNode = SKSpriteNode(color: UIColor.clearColor(), size: self.size)        addChild(screenNode)        let sky = Background(textureNamed: "sky", duration:60.0).addTo(screenNode)        let city = Background(textureNamed: "city", duration:20.0).addTo(screenNode)        let ground = Background(textureNamed: "ground", duration:5.0).addTo(screenNode)        actors = [sky, city, ground]               for actor in actors {            actor.start()        }    } } The only implemented function is didMoveToView(), which can be considered the equivalent of viewDidAppear for a UIVIewController. We define an array of Startable objects, where Startable is a protocol for making the life cycle of the scene, uniform: import SpriteKit   protocol Startable {    func start()    func stop() } This will be handy for giving us an easy way to stop the game later, when either we reach the final goal or our character dies. The Background class holds the behavior for a scrollable level: import SpriteKit   class Background {    private let parallaxNode: ParallaxNode    private let duration: Double      init(textureNamed textureName: String, duration: Double) {        parallaxNode = ParallaxNode(textureNamed: textureName)        self.duration = duration    }       func addTo(parentNode: SKSpriteNode) -> Self {        parallaxNode.addTo(parentNode)        return self    } } As you can see, the class saves the requested duration of a cycle, and then it forwards the calls to a class called ParallaxNode: // Startable extension Background : Startable {    func start() {        parallaxNode.start(duration: duration)    }       func stop() {        parallaxNode.stop()    } } The Startable protocol is implemented by forwarding the methods to ParallaxNode. How to implement the scrolling The idea of implementing scrolling is really straightforward: we implement a node where we put two copies of the same image in a tiled format. We then place the node such that we have the left half fully visible. Then we move the entire node to the left until we fully present the left node. Finally, we reset the position to the original one and restart the cycle. The following figure explains this algorithm: import SpriteKit   class ParallaxNode {    private let node: SKSpriteNode!       init(textureNamed: String) {        let leftHalf = createHalfNodeTexture(textureNamed, offsetX: 0)        let rightHalf = createHalfNodeTexture(textureNamed, offsetX: leftHalf.size.width)               let size = CGSize(width: leftHalf.size.width + rightHalf.size.width,            height: leftHalf.size.height)               node = SKSpriteNode(color: UIColor.whiteColor(), size: size)        node.anchorPoint = CGPointZero        node.position = CGPointZero        node.addChild(leftHalf)        node.addChild(rightHalf)    }       func zPosition(zPosition: CGFloat) -> ParallaxNode {        node.zPosition = zPosition        return self    }       func addTo(parentNode: SKSpriteNode) -> ParallaxNode {        parentNode.addChild(node)        return self    }   } The init() method simply creates the two halves, puts them side by side, and sets the position of the node: // Mark: Private private func createHalfNodeTexture(textureNamed: String, offsetX: CGFloat) -> SKSpriteNode {    let node = SKSpriteNode(imageNamed: textureNamed,                            normalMapped: true)    node.anchorPoint = CGPointZero    node.position = CGPoint(x: offsetX, y: 0)    return node } The half node is just a node with the correct offset for the x-coordinate: // Mark: Startable extension ParallaxNode {    func start(#duration: NSTimeInterval) {        node.runAction(SKAction.repeatActionForever(SKAction.sequence(            [                SKAction.moveToX(-node.size.width/2.0, duration: duration),                SKAction.moveToX(0, duration: 0)            ]            )))    }       func stop() {        node.removeAllActions()    } } Finally, the Startable protocol is implemented using two actions in a sequence. First, we move half the size—which means an image width—to the left, and then we move the node to the original position to start the cycle again. This is what the final result looks like: You can find the code for this version at https://github.com/gscalzo/FlappySwift/tree/stage_with_parallax_levels. Summary This article has given an idea on how to go about direction that you need to build a clone of the Flappy Bird app. For the complete exercise and a lot more, please refer to Swift by Example by Giordano Scalzo. Resources for Article: Further resources on this subject: Playing with Swift [article] Configuring Your Operating System [article] Updating data in the background [article]
Read more
  • 0
  • 0
  • 8063

article-image-your-first-swift-app
Packt
22 Jan 2016
13 min read
Save for later

Your First Swift App

Packt
22 Jan 2016
13 min read
In this article by Giordano Scalzo, the author of the book Swift 2 by Example, learning a language is just half of the difficulty in building an app; the other half is the framework. This means that learning a language is not enough. In this article, we'll build a simple Guess a Number app just to become familiar with Xcode and a part of the CocoaTouch framework. (For more resources related to this topic, see here.) The app is… Our first complete Swift program is a Guess a Number app, a classic educational game for children where the player must guess a number that's generated randomly. For each guess, the game tells the player whether the guess is greater or lower than the generated number, which is also called the secret number. It is worth remembering that the goal is not to build an Apple's App Store-ready app with a perfect software architecture but to show you how to use Xcode to build software for iOS. So forgive me if the code is not exactly clean and the game is simple. Before diving into the code, we must define the interface of the app and the expected workflow. This game presents only one screen, which is shown in the following screenshot: At the top of the screen, a label reports the name of the app: Guess a Number. In the next row, another static label field with the word between connects the title with a dynamic label field that reports the current range. The text inside the label must change every time a new number is inserted. A text field at the center of the screen is where the player will insert their guess. A big button with OK written on it is the command that confirms that the player has inserted the chosen number. The last two labels give feedback to the player, as follows: Your last guess was too low is displayed if the number that was inserted is lower than the secret number Your last guess was too high is displayed if the number that was inserted is greater than the secret number The last label reports the current number of guesses. The workflow is straightforward: The app selects a random number. The player inserts their guess. If the number is equal to the secret number, a popup tells the player that they have won and shows them the number of guesses. If the number is lower than the secret number but greater than the lower bound, it becomes the new lower bound. Otherwise, it is silently discarded. If the number is greater and lower than the upper bound, it becomes the new upper bound. Otherwise, it's again silently discarded. Building a skeleton app Let's start building the app. There are two different ways to create a new project in Xcode: using a wizard or selecting a new project from the menu. When Xcode starts, it presents a wizard that shows the recently used projects and a shortcut to create a new project, as shown in the following screenshot: If you already have Xcode open, you can select a new project by navigating to File | New | Project…, as shown in the following screenshot: Whichever way you choose, Xcode will ask for the type of app that needs to be created. The app is really simple. Therefore, we choose Single View Application, as shown in the following screenshot: Before we start writing code, we need to complete the configuration by adding the organization identifier using the reverse domain name notation and Product Name. Together, they produce a Bundle Identifier, which is the unique identifier of the app. Pay attention to the selected language, which must obviously be Swift. Here is a screenshot that shows you how to fill the form: Once you're done with this data, you are ready to run the app by navigating to Product | Run, as shown in the following screenshot: After the simulator finishes loading the app, you can see our magnificent creation: a shiny, brilliant, white page! We can stop the app by navigating to Product | Stop, as shown in the following screenshot: Now, we are ready to implement the app. Adding the graphic components When we are developing an iOS app, it is considered good practice to implement the app outside-in, starting from the graphics. By taking a look at the files generated by the Xcode template, we can identify the two files that we'll use to build the Guess a Number app: Main.storyboard: This contains the graphics components ViewController.swift: This handles all the business logic of the app Here is a screenshot that presents the structure of the files in an Xcode project: Let's start by selecting the storyboard file to add the labels. The first thing that you will notice is that the canvas is not the same size or ratio as that of an iPhone and an iPad. To handle different sizes and different devices, Apple (since iOS 5) added a constraints system called Auto Layout as a system to connect the graphics components in a relative way regardless of the actual size of the running device. As Auto Layout is beyond the scope of this article, we'll implement the created app only for iPhone 6. After deciding upon the target device, we need to resize the canvas according to the real size of the device. From the tree structure to the right, we select View Controller, as shown in the following screenshot: After doing this, we move to the right, where you will see the properties of the View Controller. There, we select the tab containing Simulated Metrics; in this, we can insert the requested size. The following screenshot will help you locate the correct tab: Now that the size is what's expected, we can proceed to add labels, text fields, and the buttons from the list at the bottom-right corner of the screen. To add a component, we must choose it from the list of components. Then, we must drag it onto the screen, where we can place it at the expected coordinates. The following screenshot shows the list of UI components called an object library: When you add a text field, pay attention to how we select Number Pad as the value for Keyboard Type, as illustrated in the following screenshot: After selecting the values for all the components, the app should appear as shown in the mockup that we had drawn earlier, which can be confirmed in the following screenshot: Connecting the dots If we run the app, the screen is the same as the one in the storyboard, but if we try to insert a number into the text field and then press the OK button, nothing happens. This is so because the storyboard is still detached from the View Controller, which handles all the logic. To connect the labels to the View Controller, we need to create instances of a label prepended with the @IBOutlet keyword. Using this signature, the graphic editor inside Xcode named Interface Builder can recognize the instances available for a connection to the components: class ViewController: UIViewController { @IBOutlet weak var rangeLbl: UILabel! @IBOutlet weak var numberTxtField: UITextField! @IBOutlet weak var messageLbl: UILabel! @IBOutlet weak var numGuessesLbl: UILabel! @IBAction func onOkPressed(sender: AnyObject) { } } We have also added a method with the @IBAction prefix, which will be called when the button is pressed. Now, let's move on to Interface Builder to connect the labels and outlets. First of all, we need to select View Controller from the tree of components, as shown in the following screenshot: In the tabs to the right, select the outlet views; the last one with an arrow is a symbol. The following screenshot will help you find the correct symbol: This shows all the possible outlets to which a component can be connected. Upon moving the cursor onto the circle beside the rangeLbl label, we see that it changes to a cross. Now, we must click and drag a line to the label in the storyboard, as shown in the following screenshot: After doing the same for all the labels, the following screenshot shows the final configurations for the outlets: For the action of the button, the process is similar. Select the circle close to the onOkPressed action and drag a line to the OK button, as shown in the following screenshot: When the button is released, a popup appears with a list of the possible events that you can connect the action to. In our case, we connect the action to the Touch Up Inside event, which is triggered when we release the button without moving from its area. The following screenshot presents the list of the events raised by the UIButton component: Now, consider a situation where we add a log command like the following one: @IBAction func onOkPressed(sender: AnyObject) { println(numberTxtField.text) } Then, we can see the value of the text field that we insert and which is printed on the debug console. Now that all the components are connected to their respective outlets, we can add the simple code that's required to create the app. Adding the code First of all, we need to add a few instance variables to handle the state, as follows: private var lowerBound = 0 private var upperBound = 100 private var numGuesses = 0 private var secretNumber = 0 Just for the sake of clarity and the separation of responsibilities, we create two extensions to the View Controller. An extension in Swift is similar to a category in Objective-C programming language, a distinct data structure that adds a method to the class that it extends. Since we don't need the source of the class that the extension extends, we can use this mechanism to add features to third-party classes or even to the CocoaTouch classes. Given this original purpose, extensions can also be used to organize the code inside a source file. This may seem a bit unorthodox, but if it doesn't hurt and is useful. So why not use it? The first extension contains the following logic of the game: private extension ViewController{ enum Comparison{ case Smaller case Greater case Equals } func selectedNumber(number: Int){ } func compareNumber(number: Int, otherNumber: Int) -> Comparison { } } Note that the private keyword is added to the extension, making the methods inside private. This means that other classes that hold a reference to an instance of ViewController can't call these private methods. Also, this piece of code shows that it is possible to create enumerations inside a private extension. The second extension, which looks like this, is used to render all the labels: private extension ViewController{ func extractSecretNumber() { } func renderRange() { } func renderNumGuesses() { } func resetData() { } func resetMsg() { } func reset(){ resetData() renderRange() renderNumGuesses() extractSecretNumber() resetMsg() } } Let's start from the beginning, which is the viewDidLoad method in the case of the View Controller: override func viewDidLoad() { super.viewDidLoad() numberTxtField.becomeFirstResponder() reset() } When the becomeFirstResponder method is called, the component called numberTxtField in our case gets the focus and the keyboard appears. After this, the reset() method is called, as follows: func reset(){ resetData() renderRange() renderNumGuesses() extractSecretNumber() resetMsg() } This basically calls the reset method of each component, as follows: func resetData() { lowerBound = 0 upperBound = 100 numGuesses = 0 } func resetMsg() { messageLbl.text = "" } Then, the method is called and is used to render the two dynamic labels, as follows: func renderRange() { rangeLbl.text = "(lowerBound) and (upperBound)" } func renderNumGuesses() { numGuessesLbl.text = "Number of Guesses: (numGuesses)" } The reset method also extracts the secret number using the arc4random_uniform function and performs some typecast magic to align numbers to the expected numeric type, as follows: func extractSecretNumber() { let diff = upperBound - lowerBound let randomNumber = Int(arc4random_uniform(UInt32(diff))) secretNumber = randomNumber + Int(lowerBound) } Now, all the action is in the onOkPressed action (pun intended): @IBAction func onOkPressed(sender: AnyObject) { guard let number = Int(numberTxtField.text!) else { let alert = UIAlertController(title: nil, message: "Enter a number", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) return } selectedNumber(number) } Here, we retrieve the inserted number. Then, if it is valid (that is, it's not empty, not a word, and so on), we call the selectedNumber method. Otherwise, we present a popup that asks for a number. This code uses the guard Swift 2.0 keyword that allows you to create a really clear code flow. Note that the text property of a UITextField function is optional, but because we are certain that it is present, we can safely unwrap it. Also, the handy Int(String) constructor converts a string into a number only if the string is a valid number. All the juice is in selectedNumber, where there is a switch case: func selectedNumber(number: Int){ switch compareNumber(number, otherNumber: secretNumber){ // The compareNumber basically transforms a compare check into an Enumeration: func compareNumber(number: Int, otherNumber: Int) -> Comparison{ if number < otherNumber { return .Smaller } else if number > otherNumber { return .Greater } return .Equals } Let's go back to the switch statement of selectedNumber; it first checks whether the number inserted is the same as the secret number: case .Equals: let alert = UIAlertController(title: nil, message: "You won in (numGuesses) guesses!", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { cmd in self.reset() self.numberTxtField.text = "" })) self.presentViewController(alert, animated: true, completion: nil) If this is the case, a popup with the number of guesses is presented, and when it is dismissed, all the data is cleaned and the game starts again. If the number is smaller, we calculate the lower bound again and then render the feedback labels, as follows: case .Smaller: lowerBound = max(lowerBound, number) messageLbl.text = "Your last guess was too low" numberTxtField.text = "" numGuesses++ renderRange() renderNumGuesses() If the number is greater, the code is similar, but instead of the lower bound, we calculate the upper bound, as follows: case .Greater: upperBound = min(upperBound, number) messageLbl.text = "Your last guess was too high" numberTxtField.text = "" numGuesses++ renderRange() renderNumGuesses() } Et voilà! With this simple code, we have implemented our app. You can download the code of the app from https://github.com/gscalzo/Swift2ByExample/tree/1_GuessTheNumber. Summary This article showed us how, by utilizing the power of Xcode and Swift, we can create a fully working app. Depending on your level of iOS knowledge, you may have found this app either too hard or too simple to understand. If the former is the case, don't loose your enthusiasm. Read the code again and try to execute the app by adding a few strategically placed println() instructions in the code to see the content of the various variables. If the latter is the case, I hope that you have found at least some tricks that you can start to use right now. Of course, simply after reading this article, nobody can be considered an expert in Swift and Xcode. However, the information here is enough to let you understand all the code. Resources for Article: Further resources on this subject: Exploring Swift [article] Swift Power and Performance [article] Creating Mutable and Immutable Classes in Swift [article]
Read more
  • 0
  • 0
  • 7303

article-image-updating-data-background
Packt
20 May 2014
4 min read
Save for later

Updating data in the background

Packt
20 May 2014
4 min read
(For more resources related to this topic, see here.) Getting ready Create a new Single View Application in Xamarin Studio and name it BackgroundFetchApp. Add a label to the controller. How to do it... Perform the following steps: We need access to the label from outside of the scope of the BackgroundFetchAppViewController class, so create a public property for it as follows: public UILabel LabelStatus { get { return this.lblStatus; } } Open the Info.plist file and under the Source tab, add the UIBackgroundModes key (Required background modes) with the string value, fetch. The following screenshot shows you the editor after it has been set: In the FinishedLaunching method of the AppDelegate class, enter the following line: UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval(UIApplication.BackgroundFetchIntervalMinimum); Enter the following code, again, in the AppDelegate class: private int updateCount;public override void PerformFetch (UIApplication application,Action<UIBackgroundFetchResult> completionHandler){try {HttpWebRequest request = WebRequest.Create("http://software.tavlikos.com") as HttpWebRequest;using (StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream())) {Console.WriteLine("Received response: {0}",sr.ReadToEnd());}this.viewController.LabelStatus.Text =string.Format("Update count: {0}/n{1}",++updateCount, DateTime.Now);completionHandler(UIBackgroundFetchResult.NewData);} catch {this.viewController.LabelStatus.Text =string.Format("Update {0} failed at {1}!",++updateCount, DateTime.Now);completionHandler(UIBackgroundFetchResult.Failed);}} Compile and run the app on the simulator or on the device. Press the home button (or Command + Shift + H) to move the app to the background and wait for an output. This might take a while, though. How it works... The UIBackgroundModes key with the fetch value enables the background fetch functionality for our app. Without setting it, the app will not wake up in the background. After setting the key in Info.plist, we override the PerformFetch method in the AppDelegate class, as follows: public override void PerformFetch (UIApplication application, Action<UIBackgroundFetchResult> completionHandler) This method is called whenever the system wakes up the app. Inside this method, we can connect to a server and retrieve the data we need. An important thing to note here is that we do not have to use iOS-specific APIs to connect to a server. In this example, a simple HttpWebRequest method is used to fetch the contents of this blog: http://software.tavlikos.com. After we have received the data we need, we must call the callback that is passed to the method, as follows: completionHandler(UIBackgroundFetchResult.NewData); We also need to pass the result of the fetch. In this example, we pass UIBackgroundFetchResult.NewData if the update is successful and UIBackgroundFetchResult.Failed if an exception occurs. If we do not call the callback in the specified amount of time, the app will be terminated. Furthermore, it might get fewer opportunities to fetch the data in the future. Lastly, to make sure that everything works correctly, we have to set the interval at which the app will be woken up, as follows: UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval(UIApplication.BackgroundFetchIntervalMinimum); The default interval is UIApplication.BackgroundFetchIntervalNever, so if we do not set an interval, the background fetch will never be triggered. There's more Except for the functionality we added in this project, the background fetch is completely managed by the system. The interval we set is merely an indication and the only guarantee we have is that it will not be triggered sooner than the interval. In general, the system monitors the usage of all apps and will make sure to trigger the background fetch according to how often the apps are used. Apart from the predefined values, we can pass whatever value we want in seconds. UI updates We can update the UI in the PerformFetch method. iOS allows this so that the app's screenshot is updated while the app is in the background. However, note that we need to keep UI updates to the absolute minimum. Summary Thus, this article covered the things to keep in mind to make use of iOS 7's background fetch feature. Resources for Article: Further resources on this subject: Getting Started on UDK with iOS [Article] Interface Designing for Games in iOS [Article] Linking OpenCV to an iOS project [Article]
Read more
  • 0
  • 0
  • 7007

article-image-getting-started-cocos2d
Packt
28 Feb 2011
8 min read
Save for later

Getting Started With Cocos2d

Packt
28 Feb 2011
8 min read
  Cocos2d for iPhone 0.99 Beginner's Guide Make mind-blowing 2D games for iPhone with this fast, flexible, and easy-to-use framework! A cool guide to learning cocos2d with iPhone to get you into the iPhone game industry quickly Learn all the aspects of cocos2d while building three different games Add a lot of trendy features such as particles and tilemaps to your games to captivate your players Full of illustrations, diagrams, and tips for building iPhone games, with clear step-by-step instructions and practical examples         Read more about this book       (For more resources on this subject, see here.) Downloading Cocos2d for iPhone Visit http://www.cocos2d-iphone.org for downloading the latest files. Search the downloads page, and there you will find the different versions available. As of this writing, Version 0.99.5 is the latest stable version. Once you have downloaded the file to your computer, uncompress the folder to your desktop, and rename it to Cocos2d. Open the uncompressed folder and take a look at its contents. Inside that folder, you will find everything you will need to make a game with Cocos2d. The following is a list of the important folders and files: Cocos2d: The bread and butter of Cocos2d. CocosDenshion: The sound engine that comes along. Cocoslive: Cocos2d comes packed with its own highscore server. You can easily set it up to create a scoreboard and ranking for your game. External: Here are the sources for Box2d and Chipmunk physics engines among other things. Extras: Useful classes created by the community. Resources: Images, sounds, tilemaps, and so on, used in the tests. Templates: The contents of the templates we'll soon install. Test: The samples used to demonstrate all the things Cocos2d can do. Tools: Some tools you may find useful, such as a ParticleView project that lets you preview how particles will look. License files: They are here in case you need to look at them. We'll start by taking a look at the samples. Time for action – opening the samples project Inside the cocos2d-iphone folder, you will find a file named cocos2d-iphone. xcodeproj. This project contains all the samples and named tests that come with the source code. Let's run one of them. Open the .xcodeproj file: In the groups and files panel you will find the source code of all the samples. There are more than 35 samples that cover all of the capabilities of Cocos2d, as shown in the following screenshot: Compile and run the SpriteTest: This project comes with a target for each of the available tests, so in order to try any of them you have to select them from the overview dropdown. Go ahead and select the SpriteTest target and click on Build and Run. If everything goes well the test should start running. Play a little with it, feel how it behaves, and be amazed by the endless possibilities.   What just happened?   You have just run your first Cocos2d application. If you want to run another sample, just select it by changing the "Active target". When you do so, the "active executable" should match to the same; if it doesn't select it manually by selecting it from the overview dropdown box. You can see which "active target" and "active executable" is selected from that overview dropdown box, they should be selected. Installing the templates Cocos2d comes with three templates. These templates are the starting point for any Cocos2d game. They let you: Create a simple Cocos2d project Create a Cocos2d project with Chipmunk as physics engine Create a Cocos2d project with Box2d as physics engine Which one you decide to use for your project depends on your needs. Right now we'll create a simple project from the first template. Time for action – installing the templates Carry out the following steps for installing the templates: Open the terminal. It is located in Applications Utilities | Terminal|. Assuming that you have uncompressed the folder on your desktop and renamed it as Cocos2d, type the following: cd desktop/Cocos2d ./install_template.sh You will see a lot of output in the terminal (as shown in the following screenshot); read it to check if the templates were installed successfully. If you are getting errors, check if you have downloaded the files correctly and uncompressed them into the desktop. If it is in another place you may get errors. We just installed the Xcode templates for Cocos2d. Now, each time you create a new project in Xcode, you will be given the choice of doing it by using a Cocos2d application. We'll see how to do that in a moment. Each time a new version of Cocos2d is released, there is a template file for that version. So, you should remember to install them each time. If you have a lot of older templates and you want to remove them, you can do so by going to Developer/Platforms/iPhoneOS. platform/Developer/Library/Xcode/Project Templates/Application and deleting the respective folder.   What just happened?   Templates are very useful and they are a great starting point for any new project. Having these templates available makes starting a new project an easy task. You will have all the Cocos2d sources arranged in groups, your AppDelegate already configured to make use of the framework and even a simple starting Layer. Creating a new project from the templates Now that you have the templates ready to use, it is time to make your first project. Time for action – creating a HelloCocos2d project We are going to create a new project named HelloCocos2d from the templates you have just installed. This won't be anything like a game, but just an introduction on how to get started. The steps are as follows: Open Xcode and select File New project| (Shift + cmd + N). 2. Cocos2d templates will appear right there along with the other Xcode project templates, as shown in the following screenshot: Select Cocos2d-0.99.1 Application. Name the project HelloCocos2d and save it to your Documents folder. Once you perform the preceding steps, the project you just created should open up. Let's take a look at the important folders that were generated: Cocos2d Sources: This is where the Cocos2d source code resides. Generally, you won't touch anything from here unless you want to make modifications to the framework or want to know how it works. Classes: This is where the classes you create will reside. As you may see, two classes were automatically created, thanks to the template. We'll explore them in a moment. Resources: This is where you will include all the assets needed for your game. Go ahead and run the application. Click on Build and go and congratulate yourself, as you have created your first Cocos2d project. Let's stop for a moment and take a look at what was created here. When you run the application you'll notice a couple of things, as follows: The Cocos2d for iPhone logo shows up as soon as the application starts. Then a CCLabel is created with the text Hello World. You can see some numbers in the lower-left corner of the screen. That is the current FPS the game is running at. In a moment, we'll see how this is achieved by taking a look at the generated classes.   What just happened?   We have just created our first project from one of the templates that we installed before. As you can see, using those templates makes starting a Cocos2d project quite easy and lets you get your hands on the actual game's code sooner. Managing the game with the CCDirector The CCDirector is the class whose main purpose is scene management. It is responsible for switching scenes, setting the desired FPS, the device orientation, and a lot of other things. The CCDirector is the class responsible for initializing OpenGL ES. If you grab an older Cocos2d project you might notice that all Cocos2d classes have the "CC" prefix missing. Those were added recently to avoid naming problems. Objective-c doesn't have the concept of namespaces, so if Apple at some point decided to create a Director class, those would collide. Types of CCDirectors There are currently four types of directors; for most applications, you will want to use the default one: NSTimer Director: It triggers the main loop from an NSTimer object. It is the slowest of the Directors, but it integrates well with UIKit objects. You can also customize the update interval from 1 to 60. Mainloop Director: It triggers the main loop from a custom main loop. It is faster than the NSTimer Director, but it does not integrate well with UIKit objects, and its interval update can't be customized. ThreadMainLoop Director: It has the same advantages and limitations as the Mainloop Director. When using this type of Director, the main loop is triggered from a thread, but it will be executed on the main thread. DisplayLink Director: This type of Director is only available in OS 3.1+. This is the one used by default. It is faster than the NSTimer Director and integrates well with UIKit objects. The interval update can be set to 1/60, 1/30, or 1/15. Those are the available Directors, most of the times you will not need to make any changes here.
Read more
  • 0
  • 0
  • 6429
article-image-network-development-swift
Packt
06 Jul 2015
30 min read
Save for later

Network Development with Swift

Packt
06 Jul 2015
30 min read
In this article by Jon Hoffman, author of the book Mastering Swift, you will learn how to use Apple's system configuration API to figure out what type of network connection we have. If we are developing applications for a mobile device (iPhone, iPod, or iPad), it is e essential to know if we have a network connection and what type of connection it is. (For more resources related to this topic, see here.) What is network development? Network development is writing code that will allow our application to send and receive data from remote services or devices. The large majority of these bulletin board services used a single modem, which meant that only one user could connect to them at any one time. These bulletin boards would seem very strange and archaic for those that grew up with the Internet; however, back then, they were how computers shared information. At that time, being able to connect to a computer across town and upload/download files was amazing. Today, however, we communicate with services and devices all over the world without thinking twice about it. Back when I first started writing applications, it was rare to develop an application that communicated over a standard network, and it was also hard to find developers with experience in network development. In today's world, just about every application has a requirement for some sort of network communication. In this article, we will show you how to connect to Representational State Transfer (REST) based services like the one Apple supplies that lets developers search the iTunes Store. Apple has documented this service very well. The documentation can be found at https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html. Before we look at how to connect to REST services, let's look at the classes in Apple's networking API that we will be using. These classes are part of Apple's powerful URL loading system. An overview of the URL session classes Apple's URL loading system is a framework of classes available to interact with URLs. Using these classes together lets us communicate with services that use standard Internet protocols. The classes that we will be using in this article to connect to and retrieve information from REST services are as follows: NSURLSession: This is the main session object. It was written as a replacement for the older NSURLConnection API. NSURLSessionConfiguration: This is used to configure the behavior of the NSURLSession object. NSURLSessionTask: This is a base class to handle the data being retrieved from the URL. Apple provides three concrete subclasses of the NSURLSessionTask class. NSURL: This is an object that represents the URL to connect to. NSMutableURLRequest: This class contains information about the request that we are making and is used by the NSURLSessionTask service to make the request. NSHTTPURLResponse: This class contains the response to our request. Now, let's look at each of these classes a little more in depth so we have a basic understanding of what each does. NSURLSession Prior to iOS 7 and OS X 10.9, when a developer wanted to retrieve contents from a URL, they used the NSURLConnection API. Starting with iOS 7 and OS X 10.9, the preferred API became NSURLSession. The NSURLSession API can be thought of as an improvement to the older NSURLConnection API. An NSURLSession object provides an API for interacting with various protocols such as HTTP and HTTPS. The session object, which is an instance of the NSURLSession, manages this interaction. These session objects are highly configurable, which allows us to control how our requests are made and how we handle the data that is returned. Like most networking API, NSURLSession is asynchronous. This means that we have to provide a way to return the response from the service back to the code that needs it. The most popular way to return the results from a session is to pass a completion handler block (closure) to the session. This completion handler is then called when the service successfully responds or we receive an error. All of the examples in this article use completion handlers to process the data that is returned from the services. NSURLSessionConfiguration The NSURLSessionConfiguration class defines the behavior and policies to use when using the NSURLSession object to connect to a URL. When using the NSURLSession object, we usually create an NSURLSessionConfiguration instance first because an instance of this class is required when we create an instance of the NSURLSession class. The NSURLSessionConfiguration class defines three session types. These are: Default session configuration: This configuration behaves similar to the NSURLConnection API. Ephemeral Session configuration: This configuration behaves similar to the default session configuration, except it does not cache anything to disk. Background Session configuration: This session allows for uploads and downloads to be performed, even when the app is running in the background. It is important to note that we should make sure that we configure the NSURLSessionConfiguration object appropriately before we use it to create an instance of the NSURLSession class. When the session object is created, it creates a copy of the configuration object that we provided it. Any changes made to the configuration object once the session object is created are ignored by the session. If we need to make changes to the configuration, we must create another instance of the NSURLSession class. NSURLSessionTask The NSURLSession service uses an instance of the NSURLSessionTask classes to make the call to the service that we are connecting to. The NSURLSessionTask class is a base class, and Apple has provided three concrete subclasses that we can use, and they are as follows: NSURLSessionDataTask: This returns the response, in memory, directly to the application as one or more NSData objects. This is the task that we generally use most often. NSURLSessionDownloadTask: This writes the response directly to a temporary file. NSURLSessionUploadTask: This is used for making requests that require a request body such as a POST or PUT request. It is important to note that a task will not send the request to the service until we call the resume() method. Using the NSURL class The NSURL object represents the URL that we are going to connect to. The NSURL class is not limited to URLs that represent remote servers but it can also be used to represent a local file on disk. In this article, we will be using the NSURL class exclusively to represent the URL of the remote service that we are connecting to. NSMutableURLRequest The NSMutableURLRequest class is a mutable subclass of the NSURLRequest class, which represents a URL load request. We use the NSMutableRequest class to encapsulate our URL and the request properties. It is important to understand that the NSMutableURLRequest class is used to encapsulate the necessary information to make our request but it does not make the actual request. To make the request, we use instances of the NSURLSession and NSURLSessionTask classes. NSURLHTTPResponse NSURLHTTPResponse is a subclass of the NSURLResponse class that encapsulates the metadata associated with the response to a URL request. The NSURLHTTPResponse class provides methods for accessing specific information associated with an HTTP response. Specifically, this class allows us to access the HTTP header fields and the response status codes. We briefly covered a number of classes in this section and it may not be clear how they all actually fit together; however, once you see the examples a little further in this article, it will become much clearer. Before we go into our examples, let's take a quick look at the type of service that we will be connecting to. REST web services REST has become one of the most important technologies for stateless communications between devices. Due to the lightweight and stateless nature of the REST base services, its importance is likely to continue to grow as more devices are connected to the Internet. REST is an architecture style for designing networked applications. The idea behind REST is instead of using complex mechanisms, such as SOAP or CORBA to communicate between devices, we use simple HTTP requests for the communication. While, in theory, REST is not dependent on the Internet protocols, it is almost always implemented using them. Therefore, when we are accessing REST services, we are almost always interacting with web servers in the same way that our web browsers interact with these servers. REST web services use the HTTP POST, GET, PUT, or DELETE methods. If we think about a standard CRUD (create/read/update/delete) application, we would use a POST request to create or update data, a GET request to read data, and a DELETE request to delete data. When we type a URL into our browser's address bar and hit Enter, we are generally making a GET request to the server and asking it to send us the web page associated with that URL. When we fill out a web form and click the the submit button, we are generally making a POST request to the server. We then include the parameters from the web form in the body of our POST request. Now, let's look at how to make an HTTP GET request using Apple's networking API. Making an HTTP GET request In this example, we will make a GET request to Apple's iTunes search API to get a list of items related to the search term Jimmy Buffett. Since we are retrieving data from the service, by REST standards, we should use a GET request to retrieve the data. While the REST standard is to use GET requests to retrieve data from a service, there is nothing stopping a developer of a web service from using a GET request to create or update a data object. It is not recommended to use a GET request in this manner, but just be aware that there are services out there that do not adhere to the REST standards. The following code makes a request to Apple's iTunes search API and then prints the results to the console: public typealias DataFromURLCompletionClosure = (NSURLResponse!,   NSData!) -> Void  public func sendGetRequest(handler: DataFromURLCompletionClosure) {  var queue = NSOperationQueue()  var sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration();     var urlString = "https://itunes.apple.com/search?term=jimmy+buffett"  if let encodeString = urlString.stringByAddingPercentEscapesUsingEncoding      (NSUTF8StringEncoding) {    if let url = NSURL(string: encodeString) {          var request = NSMutableURLRequest(URL: url)      request.HTTPMethod = "GET"      var urlSession = NSURLSession(configuration: sessionConfiguration, delegate: nil, delegateQueue: queue)            var sessionTask = urlSession.dataTaskWithRequest(request) {        (data, response, error) in                handler(response, data)      }      sessionTask.resume()      }    }} We start off by creating a type alias named DataFromURLCompletionClosure. The DataFromURLCompletionClosure type will be used for both the GET and POST examples of this `. If you are not familiar with using a typealias object to define a closure type. We then create a function named sendGetRequest() that will be used to make the GET request to Apple's iTunes API. This function accepts one argument named handler, which is a closure that conforms to the DataFromURLCompletionClosure type. The handler closure will be used to return the results from our request. Within our sendGetRequest() method, we begin by creating an instance of the NSOperationQueue class. This queue will be used by our NSURLSession instance for scheduling the delegate calls and completion handlers. We then create an instance of the NSURLSessionConfiguration class using the defaultSessionConfiguration() method, which creates a default session configuration instance. If we need to, we can modify the session configuration properties after we create it, but in this example, the default configuration is what we want. After we create our session configuration, we create our URL string. This is the URL of the service we are connecting to. With a GET request, we put our parameters in the URL itself. In this specific example, https://itunes.apple.com/search is the URL of the web service. We then follow the web service URL with a question mark (?), which indicates that the rest of the URL string consists of parameters for the web service. Parameters take the form of key/value pairs, which means that each parameter has a key and a value. The key and the value of a parameter, in a URL, are separated by an equals sign (=). In our example, the key is term and the value is jimmy+buffett. Next, we run the URL string that we just created through the stringByAddingPercentEscapesUsingEncoding() method to make sure our URL string is encoded properly. Next, we use the URL string that we just built to create an NSURL instance named url. Since we are making a GET request, this NSURL instance will represent both the location of the web service and the parameters that we are sending to it. We create an instance of the NSMutableURLRequest class using the NSURL instance that we just created. We use the NSMutableURLRequest class, instead of the NSURLRequest class, so we can set the properties needed for our request. In this example, we set the HTTPMethod property; however, we can also set other properties like the timeout interval, or add items to our HTTP header. Now, we use the sessionConfiguration variable (instance of the NSURLSessionConfiguration) and the queue (instance of NSOperationQueue) that we created at the beginning of the sendGetRequest() function to create an instance of the NSURLSession class. The NSURLSession class provides the API that we will use to connect to Apple's iTunes search API. In this example, we use the dataTaskWithRequest() method of the NSURLSession instance to return an instance of the NSURLSessionDataTask instance named sessionTask. The sessionTask instance is what makes the request to the iTunes search API. When we receive the response from the service, we use the handler callback to return both the NSURLResponse object and the NSData object. The NSURLResponse contains information about the response, and the NSData instance contains the body of the response. Finally, we call the resume() method of the NSURLSessionDataTask instance to make the request to the web service. Remember, as we mentioned earlier, an NSURLSessionTask instance will not send the request to the service until we call the resume() method. Now, let's look at how we would call the sendGetRequest() function. The first thing we need to do is to create a closure that will be passed to the sendGetRequest() function and called when the response from the web service is received. In this example, we will simply print the response to the console. Here is the code: var printResultsClosure: HttpConnect.DataFromURLCompletionClosure   = {   if let data = $1 {    var sString = NSString(data: data, encoding: NSUTF8StringEncoding)    println(sString) } } We define this closure, named printResultsClosure, to be an instance of the DataFromURLCompletionClosure type. Within the closure, we unwrap the first parameter and set the value to a constant named data. If the first parameter is not nil, we convert the data constant to an instance of the NSString class, which is then printed to the console. Now, let's call the getConnection() method with the following code: let aConnect = HttpConnect() aConnect.sendGetRequest(printResultsClosure) This code creates an instance of the HttpConnect class and then calls the sendGetRequest() method, passing the printResultsClosure closure as the only parameter. If we run this code while we are connected to the Internet, we will receive a JSON response that contains a list of items related to Jimmy Buffett on iTunes. Now that we have seen how to make a simple HTTP GET request, let's look at how we would make an HTTP Post POST request to a web service. Making an HTTP POST request Since Apple's iTunes, APIs use GET requests to retrieve data. In this section, we will use the free httpbin.org service to show you how to make a POST request. The POST service that httpbin.org provides can be found at http://httpbin.org/post. This service will echo back the parameters that it receives so we can verify our request was made properly. When we make a POST request, we generally have some data that we want to send or post to the server. This data takes the form of key-value pairs. These pairs are separated by an ampersand (&) symbol and each key is separated from its value by an equals sign (=). As an example, let's say that we want to submit the following data to our service: firstname: Jon lastname: Hoffman age: 47 years The body of the POST request would take the following format: firstname=Jon&lastname=Hoffman&age=47 Once we have the data in the proper format, we will then use the dataUsingEncoding() method, like we did with the GET request to properly encode the POST data. Since the data going to the server is in the key-value format, the most appropriate way to store this data, prior to sending it to the service, is with a Dictionary object. With this in mind, we will need to create a method that will take a Dictionary object and return a string object that can be used for the POST request. The following code will do that: func dictionaryToQueryString(dict: [String : String]) -> String { var parts = [String]() for (key, value) in dict {    var part: String = key + "=" + value    parts.append(part); } return join("&", parts) } This function loops though each key-value pair of the Dictionary object and creates a String object that contains the key and the value separated by the equals sign (=). We then use the join() function to join each item in the array separated by the specified sting. In our case, we want to separate each string with the ampersand symbol (&). We then return this newly created string to the code that called it. Now, let's create our sendPostRequest() function that will send the POST request to the httpbin.org post service. We will see a lot of similarities between this sendPostRequest() function and the sendGetRequest() function that we showed you in the Making an HTTP GET request section of this article. Let's take a look at the following code: public func sendPostRequest(handler: DataFromURLCompletionClosure) { var queue = NSOperationQueue()        var sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()    var urlString = "http://httpbin.org/post" if let encodeString =     urlString.stringByAddingPercentEscapesUsingEncoding (NSUTF8StringEncoding){    if let url: NSURL = NSURL(string: encodeString) {                     var request = NSMutableURLRequest(URL: url)      request.HTTPMethod = "POST"      var params = dictionaryToQueryString(["One":"1 and 1", "Two"  : "2 and 2"])      request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)      var urlSession = NSURLSession(configuration: sessionConfiguration, delegate: nil, delegateQueue: queue)           var sessionTask = urlSession.dataTaskWithRequest(request) {        (data, response, error) in             handler(response, data)      }      sessionTask.resume()      }    } } Now, let's walk though this code. Notice that we are using the same type alias, named DataFromURLCompletionClosure, that we used with the sendGetRequest() function. If you are not familiar with using a typealias object to define a closure type. The sendPostRequest() function accepts one argument named handler, which is a closure that conforms to the DataFromURLCompletionClosure type. The handler closure will be used to process the data from the httpbin.org service once the service responds to our request. Within our sendPostRequest() method, we start off by creating an instance of the NSOperationQueue named queue. This queue will be used by our NSURLSession instance to schedule the delegate calls and completion handlers. We then create an instance of the NSURLSessionConfiguration class using the defaultSessionConfiguration() method, which creates a default session configuration instance. We are able to modify the session configuration properties after we create it, but, in this example, the default configuration is what we want. After we created our session configuration, we create our URL string. This is the URL of the service we are connecting to. In this example, the URL is http://httpbin.org/post. Next, we run the URL string through the stringByAddingPercentEscapesUsingEncoding() method to make sure that our URL string is encoded properly. Next, we use the URL string that we just built to create an instance of the NSURL class named url. Since this is a POST request, this NSURL instance will represent the location of the web service that we are connecting to. We now create an instance of the NSMutableURLRequest class using the NSURL instance that we just created. We use the NSMutableURLRequest class, instead of the NSURLRequest class, so that we can set the properties needed for our request. In this example, we set the HTTPMethod property; however, we can also set other properties like the timeout interval, or add items to our HTTP header. Now, we use our dictionaryToQueryString() function, that we showed you at the beginning of this section, to build the data that we are going to post to the server. We then use the dataUsingEncoding() function to make sure that our data is properly encoded prior to sending it to the server, and finally, the data is added to the HTTPBody property of the NSMutableURLRequest instance. Next, we use the sessionConfiguration variable (instance of the NSURLSessionConfiguration) and the queue (NSOperationQueue) that we created at the beginning of the function to create an instance of the NSURLSession class. The NSURLSession class provides the API that we will use to connect to the post on httpbin.org's post service. In this example, we use the dataTaskWithRequest() method of the NSURLSession instance to return an instance of the NSURLSessionDataTask named sessionTask. The sessionTask instance is what makes the request to the httpbin.org's POST service. When we receive the response from the service, we use the handler callback to return both the NSURLResponse object and the NSData object. The NSURLResponse contains information about the response and the NSData instance contains the body of the response. Finally, we call the resume() method of the NSURLSessionDataTask instance to make the request to the web service. Remember, as we mentioned earlier, an NSURLSessionTask class will not send the request to the service until we call the resume() method. We can then call the sendPostRequest() method in exactly the same way that we called the sendGetRequest() method. When developing applications that communicate to other devices and services over the Internet, it is also good practice to verify that we have a network connection. When developing mobile applications, it is also good practice to verify that we are not using a mobile connection (3G, 4G, and so on) to transfer large amounts of data. Let's look at how to verify that we have a network connection and what type of connection we have. Encoding a URL In both the sendGetRequest and sendPostRequest examples, we used the stringByAddingPercentEscapesUsingEncoding() function to make sure that we had a valid URL. While this function does make sure that we have a valid URL, it does not always return the URL that we expect. In Apple's documentation of this function, it notes the following issue, in Apple's documentation of this function, it notes that it may be difficult to use this function to clean up unescaped or partially escaped URL strings where sequences are unpredictable. With this in mind, the following function is a much better way to convert a standard string to a valid URL: private func urlEncode(s: String) -> String { return CFURLCreateStringByAddingPercentEscapes(nil, s, nil,   "!*'"();:@&=+$,/?%#[]", CFStringBuiltInEncodings.UTF8.rawValue)     as! String } Within this function, we use the CFURLCreateStringByAddingPercentEscapes() function to replace the characters listed with the equivalent percent escape sequence as defined by the encoding. This is a much better function for converting a string instance to a valid URL than the stringByAddingPercentEscapesUsingEncoding() function. Checking network connection As we create applications that communicate with other devices and services over the Internet, eventually, we will want to verify that we have a network connection prior to making the network calls. Another thing to consider when we are writing mobile applications is the type of network connection that the user has. As mobile application developers, we need to keep in mind that our users probably have a mobile data plan that limits the amount of data they can send/receive in a month. If they exceed that limit, they may have to pay an extra fee. If our application sends large amounts of data, it might be appropriate to warn our user prior to sending this data. This next example will show how we can verify that we have a network connection and also tells us what type of connection we have. We will begin by importing the system configuration API and also defining an enum that contains the different connection types. We will import the system configuration API like this: import SystemConfiguration The ConnectionType enum is then defined like this: public enum ConnectionType {    case NONETWORK    case MOBILE3GNETWORK    case WIFINETWORK } Now, let's look at the code to check the network connection type: public func networkConnectionType(hostname: NSString) ->   ConnectionType {        var reachabilityRef =  SCNetworkReachabilityCreateWithName (nil,hostnamehostnamehostnamehostname.UTF8String)        var reachability = reachabilityRef.takeUnretainedValue() var flags: SCNetworkReachabilityFlags = 0 SCNetworkReachabilityGetFlags (reachabilityRef.takeUnretainedValue(), &flags) var reachable: Bool = (flags & UInt32(kSCNetworkReachabilityFlagsReachable) != 0) var needsConnection: Bool = (flags & UInt32(kSCNetworkReachabilityFlagsConnectionRequired) != 0) if reachable && !needsConnection {       // what type of connection is available    var isCellularConnection = (flags & UInt32(kSCNetworkReachabilityFlagsIsWWAN) != 0)      if isCellularConnection { // cellular Cellular connection available        return ConnectionType.MOBILE3GNETWORK;      }      else {        // wifi Wifi connection available        return ConnectionType.WIFINETWORK;      }    }    //No or unknown connection    return ConnectionType.NONETWORK } The networkConnectionType() function begins by creating a SCNetworkReachability reference. To create the SCNetworkRechabilityRef reference, we use the SCNetworkReachabilityCreateWithName() function, which creates a reachability reference to the host provided. In Swift, when we receive an unmanaged object, we should immediately convert it to a memory-managed object before we work with it. This allows Swift to manage the memory for us. For this, we use the takeUnretainedValue() function. After we get our SCNetworkReachabilityRef reference, we need to retrieve the SCNetworkReachabilityFlags enum from the reference. This is done with the SCNetworkReachabilityGetFlags() function. Once we have the network reachability flags, we can begin testing our connection. We use the bitwise AND (&) operator to see if the host is reachable and if we need to establish a connection before we can connect to the host (needsConnection). If the reachable flag is false (we cannot currently connect to the host), or if needsConnection is true (we need to establish a connection before we can connect), we return NONETWORK, which means the host is currently not reachable. If we are able to connect to the host, we then check to see if we have a cellular connection by checking the network reachability flags again. If we have a cellular connection, we return MOBILE3GNETWORK; otherwise, we assume we have a Wi-Fi connection and return WIFINETWORK. If you are writing applications that connect to other devices or services over the Internet, I would recommend putting this function in a standard library to use because you will want to check for networking connectivity, and also the type of connection that you have pretty regularly. Now that we have seen how to use Apple's networking APIs to connect to remote services, I would like to demonstrate a network library that you can use in your own applications. This network library makes it very easy and simple to connect to various types of services on the Internet. This is a library that I created and maintained, but I would definitely welcome anyone that would like to contribute to the code base. This library is called RSNetworking. RSNetworking You can find RSNetworking on GitHub with this URL https://github.com/hoffmanjon/RSNetworking. RSNetworking is a network library written entirely in the Swift programming language. RSNetworking is built using Apple's powerful URL loading system (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html), which features the NSURLSession class that we used earlier in this article. The main design goal of RSNetworking is to make it easy and quick for developers to add powerful asynchronous networking requests to their applications that are written in Swift. There are three ways that we can use RSNetworking, which are as follows: RSURLRequest: This API provides a very simple and easy interface to make single GET requests to a service. RSTransaction and RSTransactionRequest: These APIs provide a very powerful and flexible way to make both GET and POST requests to a service. This API also makes it very easy to make multiple requests to a service. Extensions: RSNetworking provides extensions to both the UIImageView and the UIButton classes to dynamically load images from a URL and insert them into the UIImageView or UIButton classes after they are loaded. Let's look at each of these APIs in greater detail and then provide some examples of how to use them. RSURLRequest With the RSURLRequest API, we can make a GET request to a service and the only thing we need to provide is the URL and the parameters we wish to send to the service. The RSURLRequest API exposes four functions. These functions are as follows: dataFromURL(url: NSURL, completionHandler handler: RSNetworking.dataFromURLCompletionClosure): This retrieves an NSData object from a URL. This is the main function and is used by the other three functions to retrieve an NSData object prior to converting it to the requested format. stringFromURL(url: NSURL, completionHandler handler: RSNetworking.stringFromURLCompletionClosure): This retrieves an NSString object from a URL. This function uses the dataFromURL() function to retrieve an NSData object and then converts it to an NSString object. dictionaryFromJsonURL(url: NSURL, completionHandler handler: RSNetworking.dictionaryFromURLCompletionClosure): This retrieves an NSDictionary object from a URL. This function uses the dataFromURL() function to retrieve an NSData object and then converts it to an NSDictionary object. The data returned from the URL should be in the JSON format for this function to work properly. imageFromURL(url: NSURL, completionHandler handler: RSNetworking.imageFromURLCompletionClosure): This retrieves a UIImage object from a URL. This function uses the dataFromURL() function to retrieve an NSData object and then converts it to a UIImage object. Now, let's look at an example on how to use the RSURLRequest API. In this example, we will make a request to Apple's iTunes search API, as we did in the Making an HTTP GET request section of this article: func rsURLRequestExample() { var client = RSURLRequest() if let testURL =  NSURL(string:"https://itunes.apple.com/search?term=jimmy+buffett&media=music") {         client.dictionaryFromJsonURL(testURL, completionHandler: resultsHandler)   } } Let's walk through this code. We begin by creating an instance of the RSURLRequest class and an instance of the NSURL class. The NSURL instance represents the URL of the service that we wish to connect to and since we are making a GET request, it also contains the parameters that we are sending to the service. If we recall from the previous Making an HTTP GET Request section, when we make a HTTP GET request, the parameters that we are sending to the service are contained within the URL itself. Apple's iTunes search API returns the results of the search in the JSON format. We can see that in the API documentation and also by printing out the results of the search to the console; therefore, we will use the dictionaryFromJsonURL() method of the RSURLRequest class to make our request to the service. We could also use the dataFromURL() or stringFromURL() methods to retrieve the data if we wanted to, but this method is specifically written to handle JSON data that is returned form a REST-based web service. The dictionaryFromJsonURL() method will take the data that is returned from the NSURLSession request and convert it to an NSDictionary object. We use the NSDictionary object here rather that Swift's Dictionary object because the web service could return multiple types (Strings, Arrays, Numbers, and so on), and if we recall, a Swift Dictionary object can have only a single type for the key and a single type for the value. When we call the dictionaryFromJsonURL() method, we pass the URL that we want to connect to and also a completion handler that will be called once the information from the service is returned and converted to an NSDicationary object. Now, let's look at our completion handler; var resultsHandler:RSURLRequestRSURLRequestRSURLRequestRSURLRequest.dictionaryFromURLCompletionClosure = { var response = $0 var responseDictionary = $1 var error = $2 if error == nil {    var res = "results"    if let results = responseDictionary[res] as? NSArray {      println(results[0])         }    else {      println("Problem")    } } else {    //If there was an error, log it    println("Error : (error)") } } Our completion handler is of the RSURLRequest.dictionaryFromURLCompletionClosure type. This type is defined in the same way as the RSTransactionRequest.dictionaryFromRSTransactionCompletionClosure type, which allows us to use this same closure for RSURLRequests and RSTransactionRequest requests. We begin the completion handler by retrieving the three parameters that were passed and assign them to the response, the responseDictionary and error variables. We then check the error variable to see if it is nil. If it is nil, then we received a valid response and can retrieve values for the NSDictionary object. In this example, we retrieve the NSArray value that is associated with the results key in the NSDictionary object that was returned from the service. This NSArray value will contain a list of items in the iTunes store that are associated with our search term. Once we have the NSArray value, we print out the first element of the array to the console. The RSURLRequest API is very good for making single GET requests to a service. Now, let's look at the RSTransaction and RSTransactionRequest API, which can be used for both POST and GET requests and should be used when we need to make multiple requests to the same service. Summary In today's world, it is essential that a developer has a good working knowledge of network development. In this article, we showed you how to use Apple's NSURLSession API, with other classes, to connect to REST-based web services. The NSURLSession API was written as a replacement for the older NSURLConnection API and is now the recommended API to use when making network requests. We ended the discussion with RSNetworking, which is an open source network library, written entirely in Swift, that I maintain. RSNetworking allows us to very quickly and easily add network functionality to our applications. Resources for Article: Further resources on this subject: Flappy Swift [article] Installing OpenStack Swift [article] Dragging a CCNode in Cocos2D-Swift [article]
Read more
  • 0
  • 0
  • 6422

article-image-cocos2d-iphone-handling-accelerometer-input-and-detecting-collisions
Packt
30 Dec 2010
4 min read
Save for later

Cocos2d for iPhone: Handling Accelerometer Input and Detecting Collisions

Packt
30 Dec 2010
4 min read
  Cocos2d for iPhone 0.99 Beginner's Guide Make mind-blowing 2D games for iPhone with this fast, flexible, and easy-to-use framework! A cool guide to learning cocos2d with iPhone to get you into the iPhone game industry quickly Learn all the aspects of cocos2d while building three different games Add a lot of trendy features such as particles and tilemaps to your games to captivate your players Full of illustrations, diagrams, and tips for building iPhone games, with clear step-by-step instructions and practical examples         Read more about this book       (For more resources on Cocos2d, see here.) Handling accelerometer input Now that we have our three basic elements roughly defined, let's focus on the player's interaction with the hero. We will start by allowing the player to move the hero using the device's built-in accelerometer. The accelerometer opens a new world of interaction between the user and the device, allowing for a lot of interesting uses. There are already lots of applications and games that use this feature in innovative ways. For example, in the game Rolando, players have to roll the main character around using the accelerometer, and here we will be doing something similar to that. The accelerometer gives you data of the current tilting of the device in the three axes, that is the x, y, and z axes. Depending on the game you are making, you will be needing all that data or just the values for one or two of the axis. Fortunately, Apple has made it very easy for developers to access the data provided by the accelerometer hardware. Time for action – moving your hero with the accelerometer We have to add a few lines of code in order to have our hero move. The end result will be the hero moving horizontally when the user tilts the device to the left or to the right. We will also do some checkovers, in order to avoid the hero moving out of the screen. The first step involved in using the accelerometer is to enable it for the CCLayers that want to receive its input. Add the following line of code to the GameLayer's init method: self.isAccelerometerEnabled = YES; Then we have to set the update interval for the accelerometer. This will set the interval at which the hardware delivers the data to the GameLayer. Add the following line afterwards: [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 60)]; Now that our GameLayer is prepared to receive accelerometer input, we just have to implement the method that receives and handles it. The following is the method that receives the input and makes our hero move. Add it to the GameLayer class: - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration{ static float prevX=0, prevY=0; #define kFilterFactor 0.05f float accelX = (float) acceleration.x * kFilterFactor + (1- kFilterFactor)*prevX; prevX = accelX;//If the hero object exists, we use the calculated accelerometer values to move him if(hero) {//We calculate the speed it will have and constrain it so it doesn't move faster than he is allowed to float speed = -20 * -accelX; if(speed > hero.movementSpeed) speed = hero.movementSpeed; else if(speed < -hero.movementSpeed) speed = -hero.movementSpeed;//We also check that the hero won't go past the borders of the screen, if he would exit the screen we don't move it if((accelX >0 || hero.mySprite.position.x >hero.mySprite.textureRect.size.width / 2) && ( accelX <0 ||hero.mySprite.position.x <320- hero.mySprite.textureRect.size.width / 2)) [hero.mySprite setPosition:ccp(hero.mySprite.position.x +speed,hero.mySprite.position.y)]; }} Run the game now. You should be able to move the hero by tilting you device, as shown in the following screenshot: The iPhone simulator does not provide a way to simulate accelerometer input, so you won't be able to test it in there; it won't move at all. What just happened? Accelerometer input can be achieved quite easily and fast. In our example, we just used the x component of the accelerometer input to handle the hero's position. The accelX variable holds the current value of the x component. This value ranges from -1 to 1, so we multiply it by the speed of the hero, then we just add that result to the current position of the hero, giving the sense of motion. We are also checking to make sure that the hero is not going off the screen before applying that movement.
Read more
  • 0
  • 0
  • 5882

article-image-cocos2d-iphone-adding-layers-and-making-simple-pause-screen
Packt
30 Dec 2010
6 min read
Save for later

Cocos2d for iPhone: Adding Layers and Making a Simple Pause Screen

Packt
30 Dec 2010
6 min read
Adding more layers to scenes As we have discussed before, a scene can contain any number of layers you want. Well, as long as performance is not an issue. As CCLayer inherits from CCNode, it can be added as the child of CCScenes or other CCLayers, allowing you to organize your content in a nice fashion. There are three types of CCLayers that you can use and combine in your games. They are as follows: CCLayer: We have been using them forever. Besides all the features inherited from CCNodes, they can receive touches and accelerometer input. CCColorLayer: They inherit from CCLayer so besides being able to receive touches and accelerometer input, their opacity and RGB colors can be changed. CCMultiplexLayer: It inherits from CCLayer and can have many children, but only one will be active at any given time. You can switch between those children. In the following examples, we will be creating some CCLayers in different ways to achieve different results. Time for action – creating a HUD to display lives and the score We will begin by building a simple Heads Up Display (HUD) for our game. Its purpose is to show some useful data about the current state of the game to the player. The idea behind making the HUD into a new layer is to simplify the logic of the GameLayer. This way, the GameLayer will only handle stuff of the game itself while leaving the HUD logic to the HUDLayer. In our game, the HUD will display the remaining lives, score, remaining bombs, and anything you want to display later. Once it is done, all we need to do in the GameLayer is send a message so the HUDLayer gets updated. The first step in creating the HUD is to add a new file to the project. In the Xcode project, select File | New file and add a new Objective-C class. Rename it as HUDLayer. Replace the contents of the HudLayer.h with the following lines: #import <Foundation/Foundation.h> #import "cocos2d.h" #import "GameScene.h" @interface HudLayer : CCLayer { CCBitmapFontAtlas * level; CCBitmapFontAtlas * score; CCBitmapFontAtlas * bombs; NSMutableArray * lives; } @property (nonatomic,retain) CCBitmapFontAtlas * level; @property (nonatomic,retain) CCBitmapFontAtlas * score; @property (nonatomic,retain) CCBitmapFontAtlas * bombs; @property (nonatomic,retain) NSMutableArray * lives; @end Do the same with the contents of the HudLayer.m file: #import "HudLayer.h" @implementation HudLayer @synthesize lives,bombs,score,level; - (id) init { if ((self = [super init])) { CCSprite * background = [CCSprite spriteWithFile:@"hud_background.png"]; [background setPosition:ccp(160,455)]; [self addChild:background]; lives = [[NSMutableArray arrayWithCapacity:3]retain]; for(int i=0;i<3;i++) { CCSprite * life = [CCSprite spriteWithFile:@"hud_life.png"]; [life setPosition:ccp(18+ 28*i,465)]; [self addChild:life]; [lives addObject:life]; } CCSprite * bomb = [CCSprite spriteWithFile:@"hud_bomb.png"]; [bomb setPosition:ccp(18,445)]; [self addChild:bomb]; GameLayer * gl = (GameLayer *)[self.parent getChildByTag:KGameLayer]; level = [CCBitmapFontAtlas bitmapFontAtlasWithString:@"Level 1" fntFile:@"hud_font.fnt"]; [level setAnchorPoint:ccp(1,0.5)]; [level setPosition:ccp(310,465)]; [level setColor:ccBLACK]; [self addChild:level]; score = [CCBitmapFontAtlas bitmapFontAtlasWithString:@"Score 0" fntFile:@"hud_font.fnt"]; [score setAnchorPoint:ccp(1,0.5)]; [score setPosition:ccp(310,445)]; [score setColor:ccBLACK]; [self addChild:score]; bombs = [CCBitmapFontAtlas bitmapFontAtlasWithString:@"X3" fntFile:@"hud_font.fnt"]; [bombs setAnchorPoint:ccp(1,0.5)]; [bombs setPosition:ccp(47,440)]; [bombs setColor:ccBLACK]; [self addChild:bombs]; } return self; } - (void) dealloc { [super dealloc]; [lives release]; } @end You can find the images and the font used above in the companion files at Support. What we have to do now is load this new layer and add it as a child of the GameScene. Change the init method of the GameScene class to look like the following: - (id) init { self = [super init]; if (self != nil) { [self addChild:[GameLayer node] z:0 tag:KGameLayer]; //kGameLayer defined in the GameScene.h file. #define kGameLayer 1 [self addChild:[HudLayer node] z:1 tag:KHudLayer]; //kHudLayer defined in the GameScene.h file. #define kHudLayer 2 } return self; } The only thing missing now is to make some changes here and there to be able to update the HUDLayer with the actual state of the game. Let's update the score and remaining lives, for now. Change the loseLife method of the GameLayer class: -(void)loseLife { self.lives--; HudLayer * hl = (HudLayer *)[self.parent getChildByTag:KHudLayer]; CCSprite * live = [hl.lives objectAtIndex:self.lives]; [live setVisible:NO]; if(self.lives ==0) { [self resetGame]; //LOSE THE GAME //GO TO GAME OVER LAYER } } Add the resetGame method: -(void)resetGame { HudLayer * hl = (HudLayer *)[self.parent getChildByTag:KHudLayer]; for(CCSprite * c in hl.lives) { [c setVisible:YES]; } self.level=1; [hl.level setString:@"Level 1"]; self.score=0; [hl.score setString:@"Score 0"]; self.bombs =3; [hl.bombs setString:@"X3"]; lives = STARTING_LIVES; } These methods will handle the displaying of the remaining lives. Finally, modify the Enemy class's destroy method, so it updates the score label instead of logging the score to the console: -(void)destroy { [self reset]; [theGame setScore:theGame.score+100]; HudLayer * hl = (HudLayer *)[theGame.parent getChildByTag:KHudLayer]; [hl.score setString:[NSString stringWithFormat:@"Score %d",theGame.score]]; } Run the game. You should see a HUD at the top of the screen (as shown in the following screenshot) with all the actual information about the state of the game. Destroy some enemies to see the score updated and lose some lives to see the "lives" icons disappear. What just happened? We just went through the steps needed to create a new layer, adding it to the scene and updating its contents. Our new layer just holds some information of the game state and displays it to the player. In order to achieve that we just added a few CCSprites and CCBitmapFontAtlases which get updated when needed. Once the HudLayer class was created we added it to the GameScene over the GameLayer, so its contents are always shown on top of the GameLayer's ones. We also provided a tag for both layers, as we will need to access them from other places. We could also have added a reference to the other layer inside them. That is all what we need to do in order to add more layers to a scene. The rest of the code just handles the updating of the contents of the HudLayer. When the player hits an enemy, a score is awarded. Then the label placed in the HUD is updated. When the hero is hit and a life is lost, we just turn the corresponding icon's visibility off, then when the game is reset we turn all of them on.
Read more
  • 0
  • 0
  • 5759
article-image-building-iphone-app-using-swift-part-2
Ryan Loomba
29 Oct 2014
5 min read
Save for later

Building an iPhone App Using Swift: Part 2

Ryan Loomba
29 Oct 2014
5 min read
Let’s continue on from Part 1, and add a new table view to our app. In our storyboard, let’s add a table view controller by searching in the bottom right and dragging. Next, let’s add a button to our main view controller that will link to our new table view controller. Similar to what we did with the web view, Ctrl + click on this button and drag it to the newly created table view controller.Upon release, choose push. Now, let’s make sure everything works properly. Hit the large play button and click on Table View. You should now be taken to a blank table: Let’s populate this table with some text. Go to File ->  New ->  File  and choose a Cocoa Touch Class. Let’s call this file TableViewController, and make this a subclass of UITableViewController in the Swift language. Once the file is saved, we’ll be presented with a file with some boilerplate code.  On the first line in our class file, let’s declare a constant. This constant will be an array of strings that will be inserted into our table: let tableArray: NSArray = ["Apple", "Orange", "Banana", "Grape", "Kiwi"] Let’s modify the function that has this signature: func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int This function returns the number of rows in our table view. Instead of setting this to zero, let’s change this to ten. Next, let’s uncomment the function that has this signature: override func numberOfSectionsInTableView(tableView: UITableView!) -> Int This function controls how many sections we will have in our table view. Let’s modify this function to return 1.  Finally, let’s add a function that will populate our cells: override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell") cell.textLabel.text = tableArray.objectAtIndex(indexPath.row) as NSString return cell }  This function iterates through each row in our table and sets the text value to be equal to the fruits we declared at the top of the class file. The final file should look like this: class TableViewController: UITableViewController { let tableArray: NSArray = ["Apple", "Orange", "Banana", "Grape", "Kiwi"] override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - Table view data source override func numberOfSectionsInTableView(tableView: UITableView!) -> Int { // #warning Potentially incomplete method implementation. // Return the number of sections. return 1 } override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete method implementation. // Return the number of rows in the section. return tableArray.count } override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell") cell.textLabel.text = tableArray.objectAtIndex(indexPath.row) as NSString return cell } } Finally, we need to go back to our storyboard and link to our custom table view controller class. Select the storyboard, click on the table view controller, choose the identity inspector and fill in TableViewController  for the custom class. If we click the play button to build our project and then click on our table view button, we should see our table populated with names of fruit: Adding a map view Click on the Sample Swift App icon in the top left of the screen and then choose Build Phases. Under Link Binary with Libraries, click the plus button and search for MapKit. Once found, click Add: In the story board, add another view controller. Search for a MKMapView and drag it into the newly created controller. In the main navigation controller, create another button named Map View, Ctrl + click + drag to the newly created view controller, and upon release choose push: Additionally, choose the Map View in the storyboard, click on the connections inspector, Ctrl + click on delegate and drag to the map view controller. Next, let’s create a custom view controller that will control our map view. Go to File -> New -> File and choose Cocoa Touch. Let’s call this file MapViewController and inherit from UIViewController. Let’s now link our map view in our storyboard to our newly created map view controller file. In the storyboard, Ctrl + click on the map view and drag to our Map View Controller to create an IBOutlet variable. It should look something like this: @IBOutlet var mapView: MKMapView! Let’s add some code to our controller that will display the map around Apple’s campus in Cupertino, CA. I’ve looked up the GPS coordinates already, so here is what the completed code should look like: import UIKit import MapKit class MapViewController: UIViewController, MKMapViewDelegate { @IBOutlet var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() let latitude:CLLocationDegrees = 37.331789 let longitude:CLLocationDegrees = -122.029620 let latitudeDelta:CLLocationDegrees = 0.01 let longitudeDelta:CLLocationDegrees = 0.01 let span:MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta) let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude) let region: MKCoordinateRegion = MKCoordinateRegionMake(location, span) self.mapView.setRegion(region, animated: true) // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } This should now build, and when you click on the Map View button, you should be able to see a map showing Apple’s campus at the center of the screen.  About the Author Ryan is a software engineer and electronic dance music producer currently residing in San Francisco, CA. Ryan started up as a biomedical engineer but fell in love with web/mobile programming after building his first Android app. You can find him on GitHub @rloomba.
Read more
  • 0
  • 0
  • 5494

article-image-iphone-issues-related-calls-sms-and-contacts
Packt
28 Jun 2011
9 min read
Save for later

iPhone: Issues Related to Calls, SMS, and Contacts

Packt
28 Jun 2011
9 min read
  iPhone JavaScript Cookbook Clear and practical recipes for building web applications using JavaScript and AJAX without having to learn Objective-C or Cocoa         Read more about this book       (For more resources related to this subject, see here.) At the time of publication, working with contacts requires us to develop native applications. But we can use JavaScript with the PhoneGap framework for building these kinds of applications for the iPhone. This is the main reason for applying this framework for the recipes included in this article. This article focuses on issues related to calls, SMS, and contacts. We'll learn how to handle contacts and how to send an SMS or place a phone call simply by interacting with the user interface. Calling a number In this recipe, you'll learn how to call a number when a user clicks on a button in the user interface. Specifically, we're going to build a simple list containing our contacts where each represents a person and their phone number. After clicking on one of these elements the dial screen will be opened and the user will only need to click on the green button for calling the specified number. We only need to build a simple XHTML file for this recipe. It can be found at code/ch08/call.html in the code bundle provided on the Packtpub site. Code files can be downloaded at the Packt website. Getting ready This recipe requires the use of the iWebKit framework. How to do it... Open your favorite text editor or IDE and create a new file called call.html. Add the standard XHTML headers and the required lines for invoking the JavaScript and CSS files provided by iWebKit: <link href="../iwebkit/css/style.css" rel="stylesheet media="screen" type="text/css" /> <script src="../iwebkit/javascript/functions.js" type="text/javascript"></script> Add the main HTML code for defining our user interface: <body class="list"> <div id="topbar"> <div id="title">Call</div> </div> <div id="content"> <ul> <li class="title">Contacts</li> <li><a class="noeffect" href="tel:555-666-777"> <span class="name">Aaron Stone</span></a></li> <li><a class="noeffect" href="tel:555-888-999"> <span class="name">Ben Jackson</span></a></li> <li><a class="noeffect" href="tel:555-222-333"> <span class="name">Bob McKenzie</span></a></li> <li><a class="noeffect" href="tel:555-444-666"> <span class="name">Luke Johnson</span></a></li> <li><a class="noeffect" href="tel:555-333-666"> <span class="name">Michael Sterling</span></a></li> </ul> </div> Now, save your new file and load it on your device. The following screenshot shows you the result of loading the file built for this recipe: How it works... The most important part of the code in this recipe is the anchor element inside each <li> tag. The href attribute of the anchor element is using a string, which represents a specific protocol followed by a number. In fact, tel identifies the protocol and the iPhone, understanding its meaning displays the dial screen allowing the user to call a number. On the other hand, the class noeffect was applied to each anchor for opening the dial screen in fullscreen mode. From a strict point of view, iWebkit is not a must for calling numbers. Safari Mobile indentifies the tel protocol by default. However, we used the mentioned framework because it helps us to easily construct a list with many items. What happens if you are using an iOS device other than the iPhone? It is not possible to call numbers from an iPad or iPod touch as of now. The code developed for this recipe works differently in these devices. Instead of calling numbers, iPad and iPod touch will ask you if you want to save numbers in the address book. Sending an SMS to a number The previous recipe explained how you can call a number from your applications. This recipe will show you how to send an SMS to a selected number. For simplicity we're going to use the same approach. We'll develop a simple XHTML file displaying a list with different contacts. When the user clicks on one of the contacts the iPhone will display the screen for sending an SMS. Getting ready As in the previous recipe we will use the iWebKit framework. As both recipes are similar, we're going to use the same XHTML file developed for the previous recipe. How to do it... Open the call.html file and replace the content of the href attribute of each <li>item for a new string starting with sms: instead of tel. For example, the first item will be the following: <li> <a class="noeffect" href="sms:555-666-777"> <span class="name">Aaron Stone</span> </a> </li> Save the new content of the original file as a new file called sms.html, then you'll be ready for testing it on your iPhone. How it works... As you've learned in the previous recipe, Safari Mobile identifies the tel protocol for calling numbers. In the same way, sms is used for sending SMS's. Also for this recipe the iWebKit is used for building the user interface. Selecting contacts Thanks to this recipe we'll learn how to select a contact from the address book of the iPhone and to display its related information. Our goal is quite simple; when the user clicks on a button, a new screen will display all available contacts. After clicking on one of these elements, the complete name of the selected contact will be displayed in the main screen. Although this recipe is very simple, you can apply it for building complex applications that require dealing with contacts available through the address book of the iPhone. The complete code for this recipe can be reached at code/ch08/queryAddress in the code bundle provided on the Packtpub site. Getting ready For this recipe we'll use three different frameworks: PhoneGap, XUI, and UiUIKit. Before continuing, make sure you have these frameworks installed on your machine. Also, remember you'll need a Mac OS X computer with the iOS SDK and Xcode installed. How to do it... The first step is to create a new PhoneGap project through Xcode. After creating your new project, the next step will be to open the main index.html file for adding our own code for this recipe. First, you should add the following lines inside the head section of the mentioned HTML file: <script type="text/javascript" src="xui-2.0.0..min.js"></script> <link rel="stylesheet" href="uiuikit/stylesheets/iphone.css" /> <style type="text/css"> #mybtn { margin-right: 12px; } </style> The next step is to comment out the JavaScript function preventBehavior() and the line below this function. Then, we're going to add our JavaScript code: function searchContact() { navigator.contacts.chooseContact(onSucessContact); } function onSucessContact(contact) { var selectedContact = contact.name; x$('#ul_contacts').html( 'inner', "<li>" + selectedContact + "</li>"); } Finally, we'll modify the original body section adding the following lines of HTML code: <div id="header"> <h1>Contacts</h1> </div> <h1>Working with contacts</h1> <p id="p_btn"> <a href="#" id="mybtn" onclick="searchContact()" class="button white">Select</a> </p> <ul id='ul_contacts'></ul> Before continuing and after applying all changes inside the code, we need to copy some files to the www directory of our project. Specifically, we're going to copy the uiuikit directory and the xui-2.0.0.min.js file. Remember, these components belong to the UiUIKit and XUI framework respectively. Save your project and click on the Build and Run button of Xcode for testing your new application. After loading the application in the iPhone Simulator, you can see a screen similar to next screenshot: When the user clicks on the button Select, a list with all the available contacts will be displayed as shown in the following screenshot: After selecting one of the items showed in the list, our application will display the data for the selected contact: How it works... PhoneGap provides a JavaScript function for accessing the predefined screen of the iPhone for selecting contacts. The name of this function is ChooseContact() and it is invoked through the navigator.contacts predefined object. It encapsulates the access to the address book of the iPhone. As a parameter, this function requires a callback method that will be invoked when a contact is selected. In our case, we implemented a function called onSuccessContact(), which captures the complete name of the contact displaying the result in a simple list. onSuccesContact uses a parameter called contact, which represents an object containing the information related to the selected contact from the address book. The XUI framework allows us to add new items to our ul list by manipulating the DOM of the HTML page. On the other hand, the UiUIKit framework was used for building the user interface for our small application. We used a bit of CSS for centering our button. Actually, we modified the right margin of this widget. The CSS style for this appears before the JavaScript code, also inside the head section.
Read more
  • 0
  • 0
  • 5358
Modal Close icon
Modal Close icon