Quantcast
Channel: Kodeco | High quality programming tutorials: iOS, Android, Swift, Kotlin, Unity, and more
Viewing all 4373 articles
Browse latest View live

Video Tutorial: Beginning Metal Part 12: Diffuse and Specular Lighting


Screencast: Server Side Swift with Vapor: Beautifying Pages with Skeleton

GameplayKit Tutorial: Artificial Intelligence

$
0
0

AI-GameplayKit-featureThe GameplayKit framework provides you with powerful tools to help you design modular and scalable games with minimal effort.

One of the best uses for GameplayKit is providing artificial intelligence for your games. Since GameplayKit is game-engine agnostic, it works with your games whether you’re using SpriteKit, SceneKit or even UIKit to power your development journey.

In this tutorial, you will learn how to incorporate an artificial intelligence into an existing game using GameplayKit.

This tutorial assumes you’re familiar with Swift and SpriteKit. If you need a refresher of Swift, check out our beginner series. If you are new to SpriteKit check out this tutorial.

Get ready to defeat pesky zombies — in a classic game of Tic-Tac-Toe.

Getting Started

Download the starter project. This project is already organized into the following folders:

  • Model: Contains the blank files to which you’ll add the GameplayKit methods to get the AI up and running.
  • Game: Contains the SpriteKit code for the game scene lifecycle.
  • Supporting Files: Contains the assets folder and all the standard files for an iOS app, such as the app delegate.

Build and run your game; it’s fully playable in its current state.

Initial Game

Time to bring some “life” into this game!

What is Artificial Intelligence?

Asking the real questions..

Asking the real questions..

Quite simply, an artificial intelligence (AI) is an algorithm that rationally analyzes data to make decisions. In video games, AI is used to bring realistic behavior to non-player characters. The best AIs will blur the line between non-player characters and human players.

The goal of any AI is to give the appearance of intelligence. However, if you gave the AI knowledge of all the rules of the game, it could easily win almost every match. Therefore, to avoid creating an undefeatable monster, it’s a good idea to introduce intentional errors.

A good example of restricting AI to make the game fair is the logic in first-person shooters (FPS). You wouldn’t want to play a game where the non-player characters have perfect aim and always know where you are.

The Strategist

The star of the show is the GKStrategist protocol. This protocol defines the general logic to decide which moves are the best ones to play.

Since this is a general purpose protocol, you can use it as a foundation to create your own custom strategist that will decide on moves according to your game’s needs. However, GameplayKit provides two specific strategist classes based on the GKStrategist protocol you can use in your games:

  • The GKMinmaxStrategist class ranks every possible move to find the best one. The best move is the one that results in the AI player winning the game, or the one that minimizes the chances of other players winning. However, since this strategist runs through every possible move to assign it a rank, the performance toll increases as the game increases in complexity.
  • The GKMonteCarloStrategist class chooses its moves by making a probabilistic guess of a move that could likely result in the AI player winning the game. This is a more efficient approach and is likely to choose a good move, but not always the best one. Even in complex games, this strategist can still perform well since it doesn’t need to rank every move from best to worst.

For this game, you’ll be using the GKMinmaxStrategist. Given that Tic-Tac-Toe is a straightforward game with a limited set of outcomes, calculating the rank of any particular move is a trivial task.

For a strategist to work its magic, it has to know the structure of your game. That’s where the game model comes into play.

The Game Model

What a pun-ch line..

What a pun-ch line..

The game model is a representation of your gameplay that GameplayKit can understand. GameplayKit uses your game model to do the following:

  • Analyze the game state by asking your model for the available moves for a given player.
  • Test future moves by using copies of your game state to test the results of hypothetical moves.
  • Rate each move to determine the optimal one. Since GameplayKit can simulate future moves, it will favor a move that provides better future results for the AI player.

Your model keeps track of all the players in the game. To GameplayKit, a player is simply a class that conforms to the GKGameModelPlayer protocol. This protocol is very easy to implement, as it only requires the player class to have a unique playerId property so your model can distinguish between players.

A move is simply a class that implements the GKGameModelUpdate protocol. According to this protocol, this class must contain a value property so it can assign the move a score based on its calculation. You’re free to design the rest of your move class according to your game’s needs.

Setting up the Model

Since this is TicTacToe, your model will consist of a 3×3 board and 2 players: the brain and the zombie. Your move class will keep track of the position of the player. You will make the AI only smart enough to determine if the next move will win the game.

Start off by opening Player.swift from the Model folder and add the GKGameModelPlayer protocol to the class declaration:

class Player: NSObject, GKGameModelPlayer {

You’ll see that Xcode warns you that Player doesn’t conform to the GKGameModelPlayer protocol.

To fix this, add the playerId property to the variable declarations below the value and name variables:

var playerId: Int

Scroll down to the init(_:) method and assign playerId an initial value:

playerId = value.rawValue

Your player class is now ready to be used by GameplayKit.

Open Move.swift and replace the contents with the following:

class Move: NSObject, GKGameModelUpdate {
 
  enum Score: Int {
    case none
    case win
  }
 
  var value: Int = 0
  var coordinate: CGPoint
 
  init(_ coordinate: CGPoint) {
    self.coordinate = coordinate
  }
 
}

Because this is the move class, you first declare conformance to the GKGameModelUpdate protocol. You will use the Score enum to define the score of a move based on whether it results in a win. Then, you provide a value property to help GameplayKit rate a move. You should never modify this property yourself during gameplay. Finally, the coordinate property is a CGPoint that contains the location on the board.

Now you can put these pieces together in your model class. Open Board.Swift and add the following class extension to the bottom of the file:

extension Board: GKGameModel {
 
  // MARK: - NSCopying
 
  func copy(with zone: NSZone? = nil) -> Any {
    let copy = Board()
    copy.setGameModel(self)
    return copy
  }
 
  // MARK: - GKGameModel
 
  var players: [GKGameModelPlayer]? {
    return Player.allPlayers
  }
 
  var activePlayer: GKGameModelPlayer? {
    return currentPlayer
  }
 
  func setGameModel(_ gameModel: GKGameModel) {
    if let board = gameModel as? Board {
      values = board.values
    }
  }
 
}

GKGameModel requires conformance to NSCopying because the strategist evaluates moves against copies of the game. The players property stores a list of all the players in the match and the activePlayer property keeps track of the player in turn. setGameModel(_:) lets GameplayKit update your game model with the new state after it makes a decision.

Next, add the following below setGameModel(_:):

func isWin(for player: GKGameModelPlayer) -> Bool {
  guard let player = player as? Player else {
    return false
  }
 
  if let winner = winningPlayer {
    return player == winner
  } else {
    return false
  }
}

This method, which is part of the starter project, determines whether a player wins the game via winningPlayer. It loops through the board to find whether either player has won and, if so, returns the winning player. You then use this result to compare it to the player that was passed onto this method.

Next, add this code right below isWin(for:):

func gameModelUpdates(for player: GKGameModelPlayer) -> [GKGameModelUpdate]? {
  // 1
  guard let player = player as? Player else {
    return nil
  }
 
  if isWin(for: player) {
    return nil
  }
 
  var moves = [Move]()
 
  // 2
  for x in 0..<values.count {
    for y in 0..<values[x].count {
      let position = CGPoint(x: x, y: y)
      if canMove(at: position) {
        moves.append(Move(position))
      }
    }
  }
 
  return moves
}
 
func apply(_ gameModelUpdate: GKGameModelUpdate) {
  guard  let move = gameModelUpdate as? Move else {
    return
  }
 
  // 3
  self[Int(move.coordinate.x), Int(move.coordinate.y)] = currentPlayer.value
  currentPlayer = currentPlayer.opponent
}

Here’s what’s going on in the code above:

  1. gameModelUpdates(for:) tells GameplayKit about all the possible moves in the current state of the game.
  2. You loop over all of the board’s positions and add a position to the possible moves array if it is not already occupied.
  3. GameplayKit calls apply(_:) after each move selected by the strategist so you have the chance to update the game state. After a player makes a move, it is now the opponent’s turn.

At the bottom of the extension add this new method:

func score(for player: GKGameModelPlayer) -> Int {
  guard let player = player as? Player else {
    return Move.Score.none.rawValue
  }
 
  if isWin(for: player) {
    return Move.Score.win.rawValue
  } else {
    return Move.Score.none.rawValue
  }
}

The AI uses score(for:) to calculate it’s best move. When GameplayKit creates its move tree, it will select the shortest path to a winning outcome.

That’s it — the model is done. Now your brain is ready to come alive!

Zombies love some healthy brains..

Zombies love some healthy brains..

Setting up the Strategist

This is where everything comes together! You’ll use the model you defined to drive the strategist.

Open Strategist.swift and replace the contents of the struct with the following:

struct Strategist {
 
  // 1
  private let strategist: GKMinmaxStrategist = {
    let strategist = GKMinmaxStrategist()
 
    strategist.maxLookAheadDepth = 5
    strategist.randomSource = GKARC4RandomSource()
 
    return strategist
  }()
 
  // 2
  var board: Board {
    didSet {
      strategist.gameModel = board
    }
  }
 
  // 3
  var bestCoordinate: CGPoint? {
    if let move = strategist.bestMove(for: board.currentPlayer) as? Move {
      return move.coordinate
    }
 
    return nil
  }
 
}

Inside of this struct:

  1. You instantiate a GKMinmaxStrategist with a maxLookAheadDepth of 5. The look ahead depth is the constraint you give a strategist to limit the number of future moves it can simulate. You also provide a random source to be the deciding factor when the strategist selects multiple moves as the best move.
  2. You keep a reference to the game model you defined and supply that to the strategist.
  3. The best coordinate is a CGPoint representing the strategist’s best move. The bestMove(for:) method will return nil if the player is in an invalid state or nonexistent.

Now only one thing remains: adding the strategist to the game.

Switch to the GameScene.swift file located inside the Game folder and add the following to the properties section near the top:

var strategist: Strategist!

With this property you keep a reference to the strategist used by the game.

Next, add following inside didMove(to:) towards the bottom, above resetGame():

strategist = Strategist(board: board)

Here you initialize the strategist with the model driving the game.

Next, add the following at the bottom of resetGame():

strategist.board = board

This ensures that every time you reset the game you also provide the strategist with a fresh game model.

Scroll down to the Touches section and add this new method right above:

fileprivate func processAIMove() {
  // 1
  DispatchQueue.global().async { [unowned self] in
    // 2
    let strategistTime = CFAbsoluteTimeGetCurrent()
    guard let bestCoordinate = self.strategist.bestCoordinate else {
      return
    }
    // 3
    let delta = CFAbsoluteTimeGetCurrent() - strategistTime
 
    let aiTimeCeiling = 0.75
    // 4
    let delay = max(delta, aiTimeCeiling)
 
    // 5
    DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
      self.updateBoard(with: Int(bestCoordinate.x), y: Int(bestCoordinate.y))
    }
  }
}

In this function you do the following:

  1. Create a dispatch queue to process the AI’s move since it could take a while.
  2. Record the starting time before the strategist decides on the best move.
  3. Calculate the time it took for the strategist to make its decision.
  4. Create a delay based on a constant so the AI will appear to take a bit of time to make a decision. On modern hardware, the AI might return a decision almost immediately so the delay gives the AI a human-like pause.
  5. Finally, you update the board on the main queue to reflect the new move.

Now you only have to call this method when it’s the AI’s turn. To do this, add the following to the bottom of updateGame():

if board.currentPlayer.value == .brain {
  processAIMove()
}

Build and run. Now the game has a mind of its own!

The Brain is Alive

If you play the game fast enough, you’ll soon notice that you can make the move for the AI. That’s not good.

To prevent this, add the following at the beginning of handleTouchEnd(_:with:):

guard board.currentPlayer.value == .zombie else {
  return
}

Build and run. Now the game will work as expected. Great job!

Game Complete

Where To Go From Here?

You can find the final project for this tutorial here.

Now you’re able to take this new knowledge you learned from this GameplayKit tutorial and add AI to your own games!

To further your knowledge of GameplayKit, check out Apple’s developer videos covering GameplayKit and its advances over time.

As an extra challenge, I encourage you to try and build more intelligence into the AI. Try adding detection of the opponent being one move away from winning and give a blocking move a higher rank. You’d only need to extend the Board.swift class and the enum in Move.swift.

We’d love you see what you can come up with. Join the discussion below to comment, ask questions or share your ideas!

The post GameplayKit Tutorial: Artificial Intelligence appeared first on Ray Wenderlich.

macOS NSTableView Tutorial

$
0
0

Update note: This macOS NSTableView tutorial has been updated to Xcode 8 and Swift 3 by Warren Burton. The original tutorial was written by Ernesto García.

Create awesome user interfaces with table views!

Create awesome user interfaces with table views!

Table views are one of the most ubiquitous controls in macOS applications, with familiar examples being Mail’s message list and Spotlight’s search results. They allow your Mac to represent tabular data in an attractive way.

NSTableView arranges data in rows and columns. Each row represents a single model object within a given data collection, and each column displays a specific attribute of a model object.

In this macOS NSTableView tutorial, you’ll use a table view to create a functional file viewer that will bear a striking resemblance to Finder. As you work through it, you’ll learn a lot about table views, such as:

  • How to populate a table view.
  • How to change its visual style.
  • How to react to user interaction, like a selection or double-click.

Ready to create your first table view? Read on!

Getting Started

Download the starter project and open it in Xcode.

Build and run to see what you’re starting with:

window at start of tutorial

You have a blank canvas from which you’ll create a cool file viewer. The starter app already has some of the functionality you’ll need to work through this tutorial.

With the application open, choose File > Open… (or use the Command+O keyboard shortcut).

open a folder

From the new window that pops up, choose any folder you want and click the Open button. You’ll see something like this in Xcode’s console:

Represented object: file:///Users/tutorials/FileViewer/FileViewer/

This message shows the selected folder’s path, and the code in the starter project passes that URL to the view controller.

If you’re curious and want to learn more about how things are implemented, here’s where you should look:

  • Directory.swift: Contains the implementation of the Directory struct that reads the content of a directory.
  • WindowController.swift: Contains the code that presents you with the folder selection panel and passes the selected directory to the ViewController.
  • ViewController.swift: Contains the implementation of the ViewController class and is where you’ll spend some time today. It’s where you’ll create the table view and show the file list.

Creating the Table View

Open Main.storyboard in the Project Navigator. Select the View Controller Scene and drop a table view from the Object Library into the view. There’s a container in the view hierachy named Table Container all ready for you.

add a table in interface builder

Next, you need to add some constraints. Click the Pin button in the Auto Layout toolbar. In the popup that appears, set the all the edge constraints as follows:

  • Top, Bottom, Leading and Trailing: 0.

constrain the table to its container

Be sure to set Update Frames to Items of New Constraints, then click Add 4 Constraints.

Take a moment to have a look at the structure of a newly created table view. As you probably gathered from its name, it follows typical table structuring:

  • It’s made up of rows and columns.
  • Each row represents a single item within the data model collection.
  • Each column displays specific attributes of the model.
  • Each column can also have a header row.
  • Header rows describe the data within a column.

table view inner structure

If you’re familiar with UITableView on iOS, you’re treading familiar waters, but they’re much deeper here in macOS. In fact, you might be surprised by the number of individual UI objects in the object hierarchy that make up an NSTableView.

NSTableView is an older and more complex control than a UITableView, and it serves a different user interface paradigm, specifically, where the user has a mouse or trackpad.

The main difference with UITableView is that you have the possibility of multiple columns and a header that can be used to interact with the table view, for example, ordering and selecting.

Together, NSScrollView and NSClipView, respectively scroll and clip the contents of the NSTableView.

There are two NSScroller objects — one each for vertical and horizontal scrolling across the table.

There are also a number of column objects. An NSTableView has columns, and these columns have headers with titles. It’s important to note that users can resize and reorder columns, though you have the power to remove this ability by setting its default to disabled.

Anatomy of NSTableView

In Interface Builder, you’ve seen the complexity of the view hierarchy of the table view. Multiple classes cooperate to build the table structure, which usually ends up looking like this:

components of a table view

These are the key parts of an NSTableView:

  • Header View: The header view is an instance of NSTableHeaderView. It’s responsible for drawing the headers at top of the table. If you need to display a custom header, you can use your own header subclasses.
  • Row View: The row view displays the visual attributes associated with every row in the table view, like a selection highlight. Each row displayed in the table has its own instance of the row view. An important distinction to make is that rows do not represent your data; that the cell’s responsibility. It only handles visual attributes like selection color or separators. You can create new row subclasses to style your table view differently.
  • Cell Views: The cell is arguably the most important object in a table view. At the intersection of a row and column, you find a cell. Each one is an NSView or NSTableCellView subclass, and its responsibility is to display the actual data. And guess what? You can create custom cell view classes to display the content however you’d like.
  • Column: The columns are represented by the NSTableViewColumn class, which is responsible for managing width and behavior of the column, such as resizing and repositioning. This class is not a view, but a controller class. You use it to specify how columns should behave, but you don’t control the visual styles of the columns with it because the header, row and cell views have got things covered.

Note: There are two modes of NSTableView. The first is a cell-based table view called an NSCell. It’s like an NSView, but older and lighter. It comes from earlier days of computing when the desktop needed optimizations in order to draw controls with minimal overhead.

Apple recommends using view-based table views, but you’ll see NSCell in many of the controls in AppKit, so it’s worth knowing what it is and where it comes from. You can read more about NSCell in Apple’s Control and Cell Programming Topics

Well, now that was a nice little jog into the basic theory behind table view structure. Now that you’ve had all that, it’s time to go back to Xcode and get to work on your very own table view.

Playing With Columns in a Table View

By default, Interface Builder creates a table view with two columns, but you need three columns to display name, date and size file information.

Go back to Main.storyboard.

Select the table view in the View Controller Scene. Make sure that you select the table view and not the scroll view that contains it.

table in the view hierarchy

Open the Attributes Inspector. Change the number of Columns to 3. It’s as simple as that! Your table view now has three columns.

Next, check the Multiple checkbox in the Selection section, because you want to select multiple files at once. Also check Alternating Rows in the Highlight section. When enabled, this tells the table view to use alternating row colors for its background, just like Finder.

configure table attributes

Rename the column headers so the text is more descriptive. Select the first column in the View Controller Scene.

configure-column

Open the Attributes Inspector and change the column Title to Name.

change the header title in attributes

Repeat the operation for the second and third column, changing the Title to Modification Date and Size, respectively.

Note: There is an alternative method for changing the column title. You can double-click directly on the header on the table view to make it editable. Both ways have exactly the same end result, so go with whichever method you prefer.

Last, if you can’t see the Size column yet, select the Modification Date column and resize to 200. It beats fishing around for the resize handle with your mouse. :]

resize modification date if needed

Build and run. Here’s what you should see:

table with configured headers

Changing How Information is Represented

In its current state, the table view has three columns, each containing a cell view that shows text in a text field.

But it’s kind of bland, so spice it up by showing the icon of the file next to the file name. Your table will look much cleaner after this little upgrade.

You need to replace the cell view in the first column with a new cell type that contains an image and a text field.

You’re in luck because Interface Builder has this type of cell built in.

Select the Table Cell View in the Name column and delete it.

delete this view

Open the Object Library and drag and drop an Image & Text Table Cell View into either the first column of the table view or the View Controller Scene tree, just under the Name table view column.

add a new cell type in interface builder

Now you’re whipping things into shape!

Assigning Identifiers

Every cell type needs an assigned identifier. Otherwise, you’ll be unable to create a cell view that corresponds to a specific column when you’re coding.

Select the cell view in the first column, and in the Identity Inspector change the Identifier to NameCellID.

edit column identifiers

Repeat the process for the cell views in the second and third columns, naming the identifiers DateCellID and SizeCellID respectively.

Populating the Table View

Note: There are two ways that you can populate a tableview, either using the datasource and delegate protocols you’ll see in this macOS NSTableView tutorial, or via Cocoa bindings. The two techniques are not mutually exclusive and you may use them together at times to get what you want.

The table view currently knows nothing about the data you need to show or how to display it, but it does need to be looped in! So, you’ll implement these two protocols to provide that information:

  • NSTableViewDataSource: tells the table view how many rows it needs to represent.
  • NSTableViewDelegate: provides the view cell that will be displayed for a specific row and column.

population flow of a table view

The visualization process is a collaboration between the table view, delegate and data source:

  1. The table view calls the data source method numberOfRows(in:) that returns the number of rows the table will display.
  2. The table view calls the delegate method tableView(_:viewFor:row:) for every row and column. The delegate creates the view for that position, populates it with the appropriate data, and then returns it to the table view.

Both methods must be implemented in order to show your data in the table view.

Open ViewController.swift in the Assistant editor and Control-drag from the table view into the ViewController class implementation to insert an outlet.

add an outlet to the tableview

Make sure that the Type is NSTableView and the Connection is Outlet. Name the outlet tableView.

define the outlet

You can now refer to the table view in code using this outlet.

Switch back to the Standard Editor and open ViewController.swift. Implement the required data source method in the ViewController by adding this code at the end of the class:

extension ViewController: NSTableViewDataSource {
 
  func numberOfRows(in tableView: NSTableView) -> Int {
    return directoryItems?.count ?? 0
  }
 
}

This creates an extension that conforms to the NSTableViewDataSource protocol and implements the required method numberOfRows(in:) to return the number files in the directory, which is the size of the directoryItems array.

Now you need to implement the delegate. Add the following extension at the end of ViewController.swift:

extension ViewController: NSTableViewDelegate {
 
  fileprivate enum CellIdentifiers {
    static let NameCell = "NameCellID"
    static let DateCell = "DateCellID"
    static let SizeCell = "SizeCellID"
  }
 
  func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
 
    var image: NSImage?
    var text: String = ""
    var cellIdentifier: String = ""
 
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .long
    dateFormatter.timeStyle = .long
 
    // 1
    guard let item = directoryItems?[row] else {
      return nil
    }
 
    // 2
    if tableColumn == tableView.tableColumns[0] {
      image = item.icon
      text = item.name
      cellIdentifier = CellIdentifiers.NameCell
    } else if tableColumn == tableView.tableColumns[1] {
      text = dateFormatter.string(from: item.date)
      cellIdentifier = CellIdentifiers.DateCell
    } else if tableColumn == tableView.tableColumns[2] {
      text = item.isFolder ? "--" : sizeFormatter.string(fromByteCount: item.size)
      cellIdentifier = CellIdentifiers.SizeCell
    }
 
    // 3
    if let cell = tableView.make(withIdentifier: cellIdentifier, owner: nil) as? NSTableCellView {
      cell.textField?.stringValue = text
      cell.imageView?.image = image ?? nil
      return cell
    }
    return nil
  }
 
}

This code declares an extension that conforms to the NSTableViewDelegate protocol and implements the method tableView(_:viewFor:row). It’s then called by the table view for every row and column to get the appropriate cell.

There’s a lot going on the method, so here’s a step-by-step breakdown:

  1. If there is no data to display, it returns no cells.
  2. Based on the column where the cell will display (Name, Date or Size), it sets the cell identifier, text and image.
  3. It gets a cell view by calling make(withIdentifier:owner:). This method creates or reuses a cell with that identifier. Then it fills it with the information provided in the previous step and returns it.

Next up, add this code inside viewDidLoad():

tableView.delegate = self
tableView.dataSource = self

Here you tell the table view that its data source and delegate will be the view controller.

The last step is to tell the table view to refresh the data when a new directory is selected.

First, add this method to the ViewController implementation:

func reloadFileList() {
  directoryItems = directory?.contentsOrderedBy(sortOrder, ascending: sortAscending)
  tableView.reloadData()
}

This helper method refreshes the file list.

First, it calls the directory method contentsOrderedBy(_:ascending) and returns a sorted array with the directory files. Then it calls the table view method reloadData() to tell it to refresh.

Note that you only need to call this method when a new directory is selected.

Go to the representedObject observer didSet, and replace this line of code:

print("Represented object: \(url)")

With this:

directory = Directory(folderURL: url)
reloadFileList()

You’ve just created an instance of Directory pointing to the folder URL, and it calls the reloadFileList() method to refresh the table view data.

Build and run.

Open a folder using the menu File > Open… or the Command+O keyboard shortcut and watch the magic happen! Now the table is full of contents from the folder you just selected. Resize the columns to see all the information about each file or folder.

your table now shows content

Nice job!

Table View Interaction

In this section, you’ll work with some interactions to improve the UI.

Responding to User Selection

When the user selects one or more files, the application should update the information in the bottom bar to show the total number of files in the folder and how many are selected.

In order to be notified when the selection changes in the table view, you need to implement tableViewSelectionDidChange(_:) in the delegate. This method will be called by the table view when it detects a change in the selection.

Add this code to the ViewController implementation:

func updateStatus() {
 
  let text: String
 
  // 1
  let itemsSelected = tableView.selectedRowIndexes.count
 
  // 2
  if (directoryItems == nil) {
    text = "No Items"
  }
  else if(itemsSelected == 0) {
    text = "\(directoryItems!.count) items"
  }
  else {
    text = "\(itemsSelected) of \(directoryItems!.count) selected"
  }
  // 3
  statusLabel.stringValue = text
}

This method updates the status label text based on the user selection.

  1. The table view property selectedRowIndexes contains the indexes of the selected rows. To know how many items are selected, it just gets the array count.
  2. Based on the number of items, this builds the informative text string.
  3. Sets the status label text.

Now, you just need to invoke this method when the user changes the table view selection. Add the following code inside the table view delegate extension:

func tableViewSelectionDidChange(_ notification: Notification) {
  updateStatus()
}

When the selection changes this method is called by the table view, and then it updates the status text.

Build and run.

selection label now configured

Try it out for yourself; select one or more files in the table view and watch the informative text change to reflect your selection.

Responding to Double-Click

In macOS, a double-click usually means the user has triggered an action and your program needs to perform it.

For instance, when you’re dealing with files you usually expect the double-clicked file to open in its default application and for a folder, you expect to see its content.

You’re going to implement double-click responses now.

Double-click notifications are not sent via the table view delegate; instead, they’re sent as an action to the table view target. But to receive those notifications in the view controller, you need to set the table view’s target and doubleAction properties.

Note: Target-action is a pattern used by most controls in Cocoa to notify events. If you’re not familiar with this pattern, you can learn about it in the Target-Action section of Apple’s Cocoa Application Competencies for macOS documentation.

Add the following code inside viewDidLoad() of the ViewController:

tableView.target = self
tableView.doubleAction = #selector(tableViewDoubleClick(_:))

This tells the table view that the view controller will become the target for its actions, and then it sets the method that will be called after a double-click.

Add the tableViewDoubleClick(_:) method implementation:

func tableViewDoubleClick(_ sender:AnyObject) {
 
  // 1
  guard tableView.selectedRow >= 0,
      let item = directoryItems?[tableView.selectedRow] else {
    return
  }
 
  if item.isFolder {
    // 2
    self.representedObject = item.url as Any
  }
  else {
    // 3
    NSWorkspace.shared().open(item.url as URL)
  }
}

Here’s the above code broken out step-by-step:

  1. If the table view selection is empty, it does nothing and returns. Also note that a double-click on an empty area of the table view will result in an tableView.selectedRow value equal to -1.
  2. If it’s a folder, it sets the representedObject property to the item’s URL. Then the table view refreshes to show the contents of that folder.
  3. If the item is a file, it opens it in the default application by calling the NSWorkspace method openURL()

Build and run and check out your handiwork.

Double-click on any file and observe how it opens in the default application. Now choose a folder and watch how the table view refreshes and displays the content of that folder.

Whoa, wait, did you just create a DIY version of Finder? Sure looks that way!

Sorting Data

Everybody loves a good sort, and in this next section you’ll learn how to sort the table view based on the user’s selection.

One of the best features of a table is one- or two-click sorting by a specific column. One click will sort it in ascending order and a second click will sort in descending order.

Implementing this particular UI is easy because NSTableView packs most of the functionality right out of the box.

Sort descriptors are what you’ll use to handle this bit, and they are simply instances of the NSSortDescriptor class that specify the desired attribute and sort order.

After setting up descriptors, this is what happens: clicking on a column header in the table view will inform you, via the delegate, which attribute should be used, and then the user will be able sort the data.

Once you set the sort descriptors, the table view provides all the UI to handle sorting, like clickable headers, arrows and notification of which sort descriptor was selected. However, it’s your responsibility to order the data based on that information, and refresh the table view to reflect the new order.

You’ll learn how to do that right now.

Woot!

Add the following code inside viewDidLoad() to create the sort descriptors:

// 1
let descriptorName = NSSortDescriptor(key: Directory.FileOrder.Name.rawValue, ascending: true)
let descriptorDate = NSSortDescriptor(key: Directory.FileOrder.Date.rawValue, ascending: true)
let descriptorSize = NSSortDescriptor(key: Directory.FileOrder.Size.rawValue, ascending: true)
 
// 2
tableView.tableColumns[0].sortDescriptorPrototype = descriptorName
tableView.tableColumns[1].sortDescriptorPrototype = descriptorDate
tableView.tableColumns[2].sortDescriptorPrototype = descriptorSize

This is what this code does:

  1. Creates a sort descriptor for every column, complete with a key (Name, Date or Size), that indicates the attribute by which the file list can be ordered.
  2. Adds the sort descriptors to each column by setting its sortDescriptorPrototype property.

When the user clicks on any column header, the table view will call the data source method tableView(_:sortDescriptorsDidChange:), at which point the app should sort the data based on the supplied descriptor.

Add the following code to the data source extension:

func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
  // 1
  guard let sortDescriptor = tableView.sortDescriptors.first else {
    return
  }
  if let order = Directory.FileOrder(rawValue: sortDescriptor.key!) {
    // 2
    sortOrder = order
    sortAscending = sortDescriptor.ascending
    reloadFileList()
  }
}

This code does the following:

  1. Retrieves the first sort descriptor that corresponds to the column header clicked by the user.
  2. Assigns the sortOrder and sortAscending properties of the view controller, and then calls reloadFileList(). You set it up earlier to get a sorted array of files and tell the table view to reload the data.

Build and run.

sortable-columns

Click any header to see your table view sort data. Click again in the same header to alternate between ascending and descending order.

You’ve built a nice file viewer using a table view. Congratulations!

Where to Go From Here?

You can download the completed project here.

This macOS NSTableView tutorial covered quite a bit, and you should now feel much more confident in your ability to use table views to organize data. In addition, you also covered:

  • The basics of table view construction, including the unique qualities of headers, rows, columns and cells.
  • How to add columns to display more data.
  • How to identify various components for later reference.
  • How to load data in the table.
  • How to respond to various user interactions.

There is a lot more you can do with table views to build elegant UI for your app. If you’re looking to learn more about it, consider the following resources:

If you have any questions or comments on this tutorial, feel free to join the discussion below in the forums!

The post macOS NSTableView Tutorial appeared first on Ray Wenderlich.

Video Tutorial: Beginning Metal Part 13: Creating a Game, Part 1

Video Tutorial: Beginning Metal Part 14: Making a Game, Part 2

Video Tutorial: Beginning Metal Part 15: Conclusion

Readers’ App Reviews – November 2016

$
0
0

Review-2016-11-feature

I hope everyone had a great Thanksgiving. For me, it was a chance to relax and be thankful to build apps on the best platform ever!

You all weren’t relaxing too much though. My inbox is full of apps from your fellow raywenderlich.com readers. I’ve downloaded them all and picked a few to share with you.

This month we have:

  • An app to make you a rockstar sound mixer
  • Some games you won’t be able to put down
  • An app to find out whats going on around you
  • And of course, much more!

Keep reading to see the latest apps released by raywenderlich.com readers like you.

Partly Sunny

PartlySunny
We all have a favorite weather app, and my new favorite is Partly Sunny.

Partly Sunny shows the most important information quickly for each location you care about: highs, lows, current temperature, and conditions. Thanks to its integration with Dark Sky, it can also give great information for the near future. For example, it might tell you it will rain in 12 minutes, or snow will continue for 35 minutes.

When you tap a location, you can get a very detailed forecast. You’ll see the entire day hour by hour graphed with temperatures and conditions. Even more information is available like visibility distances, humidity, wind speed, sunrise and sunset times, and more. You can also swipe up past the hourly charts to see a chart for the next 7 days with temperature ranges and expected conditions. Each day also has a detailed view.

Partly Sunny is packed with even more features. It has a rain graphs that show upcoming rain based on strength. You can graph hourly wind speed estimations, humidities, precipitation and more. It even has a dark theme for those that really love a little less white.

If you’re looking to try a new weather app, give Partly Sunny a try. If you’re not looking for a new weather app, give it a try anyway, it just might change your forecast. ;]

MyRedBag

MyRedBag
MyRedBag is the one stop shop for recipes and grocery lists.

MyRedBag lets you create and save recipes in an easy to manage index. You can even search recipes from other users to find new ideas for your kitchen. You can also easily add the ingredients from any recipe to your grocery list. MyRedBag even lets you schedule your meals in a meal planner. Then make sure you have a grocery list for everything you need to make it happen.

You can share your list with friends and family to make shopping a group exercise. And you can share your recipes with the community so others can taste your special creations.

You can even find stores in your area and submit grocery orders for delivery or pickup based on availability for the stores in your area.

MyRedBag is the one and only Recipe and Shopping app you should ever need.

iMonstickers

iMonstickers
iMonstickers were painstakingly designed to help you express emotions… if your emotions involve vampires, ghosts, or mummies. :]

iMonstickers has a sticker for everything. It’s got sad stickers, surprise stickers, scared, shy, and more! iMonstickers were great for Halloween, but we all have a little monster in us year round. ;]

hearEQ

hearEQ
hearEQ will help you learn, train, and perfect your ear for adjusting an equalizer.

The ability to adjust an equalizer effectively can transform music. Whether you’re a sound engineer, musician, or just an avid listener, a well tuned equalizer can take music to the next level.

hearEQ will help you understand how each frequency band can affect the music. You’ll be able to recreate popular effects or just balance music. hearEQ uses your favorite songs on your device to create custom ear training exercises that will teach you about individual frequency bands and then help you hone in your ear as you practice tuning. hearEQ supports both standard 10-band and 30-band equalizers like you’d find in iTunes or even professional boards.

There is also a quiz mode playing your song with random adjustments and letting you listen and guess the applied equalization. You’ll get 10 questions covering ten frequencies and a score to finish. As your score goes up, you should notice an improved ability to hear the difference in the music. Was the music sounding a bit hollow? Probably a 1000Hz cut. Was it too muddy? Probably a 500Hz boost.

hearEQ is great for beginners looking to get into sound mixing. But experts also appreciated the change to clearly control and quiz themselves to improve their sensitive ears.

San Jacinto

SanJacinto
The Battle of San Jacinto was an important battle in Texas history. This app brings the book “The Battle of San Jacinto” by James W. Pohl to life on the iPad and iPhone.

The original text is enhanced with pictures from the battle sights today as well as illustrations of how the site looked before. There are panoramic photos of the areas today. You can pan around with your finger or even move your iPad around to feel like you’re there. Zoom in for complete details.

There are also maps of the battlegrounds and surrounding area from the Southwestern Historical Quarterly by Jeffrey D. Dunn. You can get an idea of what the landscape was when the battle took place and how landmarks influenced the outcome.

San Jacinto is a fantastic historical reference and immersive learning tool.

Can Knockout

CanKnockout
Can Knockout is a classic carnival game right on your iPhone or iPad so you can play anytime.

Can Knockout shows a stack of cans and lets you flick a baseball to knock them down. You only get so many baseballs so you’ll have to aim carefully.

Each time you knock down a stack, you’ll get a chance at a new stack in a different challenging layout. As you work through levels you’ll even encounter some exploding cans.

Can Knockout is definitely addicting. My highscore is 55 if you care to try and beat it. ;]

Note: Want to build an app like this? Check out our How to Make a Game Like Can Knockdown tutorial by Ryan Ackermann!

iPlaySax

iPlaySax
Whether you are already great at playing the saxophone or are just getting started, iPlaySax is the app for you.

iPlaySax is an all around companion to saxophone musicians everywhere. The highlight of the app is sheet music specifically written and arranged for the app. They cover a variety of skill levels and styles. You can play the sheet music as is if you’d like and even record yourself as you play.

Each piece is also recorded by a real saxophone professional, so you can also play along or even play a duet! Each part was recorded separately so you can select what you’d like to play and the app will fill in the rest.

There are also instructional pieces. There is a finger position chart for beginners or anyone needing a refresher for individual notes. There are video tutorials teaching you anything from breathing techniques to finger exercises. You can buy additional music right in the app or also check out some free music by sharing the app with friends.

iPlaySax is also completely free! So its definitely worth checking out if you’re a saxophone player.

ENY: Events Near You

ENY
Ever wonder what might be going on in town? Maybe you’re visiting a new city or just at home looking for something to do. Events Near You will help you find something to do nearby anytime.

From garage sales to concerts to pickup basketball, ENY will show you a map of stuff going on around you. You can easily filter the map based on what interests you using keywords. Once you find something you like you’ll see various information like number of attendees, times, descriptions, and directions.

ENY will also let you save keywords for events that interest you often. When a new event with that keyword is posted, you’ll be notified if you’re nearby when it starts. A great way to get keyed into the local events without even looking for them.

Best of all, ENY isn’t only useful if everyone in your community uses it. It draws from some other popular services like Meetup. So even if you’re the only ENY user in your town right now, you’ll still find some events. And it will only get better as you invite your friends. :]

Blob.IT

Blobit
Some of us are always on the hunt for a new word game. This month, one fell right into my lap. :]

Blob.IT has a bit of a different system. Each level has a time limit and fixed number of letters. Letters will highlight and you must create the hidden word from the highlighted letters.

Not just any word will do. Blob.IT has hand selected words. So it won’t be enough to come up with “tone” if the scrambled highlighted word is “note.” So you’ll need to dig deep sometimes. The time limit is for the whole bank of letters, so you don’t have long for each word. Keep going as long as you can before the time runs out.

Blob.IT has GameCenter support with both achievements and leaderboards so you can see how you stack up. You can even challenge your friends to multiplayer.

Hell Birdie

HellBird
Hell birdie is lost in our world and needs your help to get back to his dark home.

Hell Birdie is definitely challenging. Its a bit similar to flappy bird but with some interested tweaks. You tap to bounce, but taps on the left of the screen bounce you left and taps on the right bounce you right. Rather than flying side to side, you’re trying to slowly advance up through obstacles. The combination or upward movement and limited movement controls, makes it an easy to game to pick up but difficult to master.

Hell Birdie is our addicting game of the month. The perfect mix of simple mechanics with challenging gameplay makes it hard to just put down. You always want to get just a little… bit… further! ;]

Where To Go From Here?

Each month, I really enjoy seeing what our community of readers comes up with. The apps you build are the reason we keep writing tutorials. Make sure you tell me about your next one, submit here.

If you saw an app your liked, hop to the App Store and leave a review! A good review always makes a dev’s day. And make sure you tell them you’re from raywenderlich.com; this is a community of makers.

If you’ve never made an app, this is the month! Check out our free tutorials to become an iOS star. What are you waiting for – I want to see your app next month.

The post Readers’ App Reviews – November 2016 appeared first on Ray Wenderlich.


Screencast: Server Side Swift with Vapor: Making a Web App

3D Apple Games by Tutorials Update Now Available!

$
0
0

igt2-update-featureGood news — we’ve released an update to 3D Apple Games by Tutorials, Second Edition!

This update adds several resources, icons, utility packages and 3D models to the downloadable book package. Previous editions might not have had all of these directories included in the download, so we’ve repackaged the entire collection of resources.

Here’s the list of resources we’ve added, by chapter:

  • Chapter 3, Physics: Extensions and helper files
  • Chapter 6, SceneKit Editor: Helper utilities, icons and game art assets
  • Chapter 9, Geometric Shapes: Chapter scene files
  • Chapter 11, Materials: Game asset files
  • Chapter 13, Shadows: Chapter scene files
  • Chapter 14, Intermediate Collision Detection: Extensions and helper files
  • Chapter 15, Motion Control: Game sound assets
  • Chapter 16, macOS Games: Icons and helper files
  • Chapter 17, tvOS Games: Icons and art assets
  • Chapter 18, watchOS Games: Icons and helper files
  • Chapter 19, Transitions: Art assets and helper files
  • Chapter 24, 3D Art for Programmers: Model asset files

How to Get the Update

This free update is available today for all 3D Apple Games by Tutorials customers.

  • If you’ve already bought the 3D Apple Games by Tutorials PDF, you can download the updated book immediately on your My Loot page.
  • If you don’t have 3D Apple Games by Tutorials yet, you can grab your own updated copy in our store.
  • Hat tip to all our forum members and readers who emailed in to help diagnose and correct this issue!

    The post 3D Apple Games by Tutorials Update Now Available! appeared first on Ray Wenderlich.

    Instagram Dev, Swift Speaker & Swift Weekly Brief: A Top Dev Interview With Jesse Squires

    $
    0
    0
    Jesse Squires

    Jesse Squires

    Welcome to another installment of our Top App Dev Interview series. Each interview in this series focuses on a successful mobile app or developer and the path they took to get where they are today. Today’s special guest is Jesse Squires.

    Jesse is a Swift guru, technology writer and speaker. He is best known for running the Swift Weekly Brief and is currently an iOS developer at Instagram.

    When he’s not busy working at Instagram, Jesse tours the world giving talks at conferences and meetup groups, including FrenchKit, Swift Summit & Realm. Jesse also contributes to many open-source projects.

    Inside Instagram

    Can you please describe the process of working within Instagram, and how that compares to a similar process when you are an indie developer?

    Working as an indie developer, you have to do much more than just be a developer. You’re also a product manager, beta tester, designer and everything else.

    Within a company, it’s all about utilizing many people’s skills. For example, we have entire teams looking after each aspect of the build, and over 500 million monthly active users constantly using the app providing feedback. It really boils down to resources – this is key. The more resources you have the fewer hats you have to wear.

    My most recent work at Instagram (that’s public) was IGListKit and more broadly incorporating the framework across the app. I have been helping Ryan Nystrom move the project forward and engage with the community on Github.

    If I was to find a bug at Instagram, can you describe the process of the work? For example Elaboration, Development, Testing. How does it flow through the scrum process?

    We work in a very self-driven way. There is no formal scrum process. If you find a bug, you usually just fix it right away or create a task and hand it off to whomever “owns” that area of the codebase if you aren’t familiar with it. For other bug reports, you just prioritize/triage them like you would elsewhere.

    We have a similar process when adding new features it consists of ideation, design, and prototyping — with collaboration across Product, Design, and Engineering. Once we figure out what we want to build, we’ll break up the work into tasks and start building.

    There’s also a strong “dog-fooding” culture at Instagram/Facebook so employees are always using the latest internal builds of the app and providing feedback.

    The new Instagram offices that Jesse works in.

    The new Instagram offices that Jesse works in.

    I note that Instagram push releases almost every week if not more. What’s the process to be able to achieve this?

    It’s a pretty straightforward process. We work on master and cut a release branch every 2 weeks. The release branch “soaks” for 2 weeks and we cherry pick commits for bug fixes as needed, then submit to the App Store. The majority of this is automated.

    I think the key is that there are no exceptions — we cut and ship every 2 weeks. If your work isn’t finished, you just wait until the next cut — but we never miss or delay a cut.

    We don’t use Jenkins to manage this; we use Facebook’s CI infra. But, for all intents and purposes it works the same way as something like Jenkins, Travis-CI, etc.

    For source control, we use mercurial and phabricator. If you aren’t familiar with these, the analogous tools would be git and GitHub.

    What’s your development workflow like?

    Our development workflow is pretty common:

    1. Make changes.
    2. Submit a diff for review.
    3. A team member needs to approve.
    4. CI runs tests.
    5. Your diff is merged.
    6. A new internal build is eventually available for dog-fooders to download.

    Contributing to the Community

    You are highly active in the open source community. What benefits have you seen from doing that?

    I attribute most of my success to open source. This definitely isn’t true for everyone, though. I was lucky enough to start a project that became really popular. And I was privileged enough to have time to get involved in open source in the first place. Not everyone has that opportunity.

    In the beginning it was about everything I learned:

    • How to use git better
    • How to use GitHub
    • How to collaborate remotely with dozens of contributors
    • How to manage a large project
    • How to triage issues
    • How to manage branches
    • How to maintain stability
    • How to design open and modular APIs
    • Semantic versioning
    • …the list goes on and on!

    With a popular open source project, you receive a ton of feedback — positive and negative. All of it is valuable and all of it helps you grow and learn.

    You are well known for curating the Swift Weekly Brief, a newsletter about the latest developments on swift.org. What made you decide to start this newsletter?

    This happened by accident. I was so interested in open source Swift when it was announced, and I wrote a few blog posts on my personal site. The community seemed to enjoy and appreciate them, so I decided to move it to a dedicated site and make it “a thing”.

    It takes multiple hours a week to put a newsletter together, but I usually do it in small chunks as I go so it never seems like it takes too much of my time. For the blog posts, GitHub activity and mailing lists — it’s pretty much what I’m reading and interested in already. I would be doing much of this on my own, so I figured I might as well share it with the community as I go.

    It’s certainly beneficial for me personally, too. I already want to stay up-to-date with everything that’s going on with Swift, so this commitment to publish the newsletter ensures that happens.

    Recently you decided to open up the Swift Weekly Brief to external contributors, with the goal of making it a community newsletter, rather than your own. What made you decide to do this, and how can people contribute?

    As I mentioned, open source has benefited me in numerous ways, and I want to give others an opportunity to contribute — if they want. There’s no reason a newsletter like this can’t be run and managed like a “regular” open source project, like AFNetworking. Bringing other peoples’ experiences and perspectives to any project makes it significantly better in my experience.

    On the other side, part of that is me wanting a break! :] As you may expect, some weeks I’m busier than others so it’s really nice to have some help if I don’t have time to put the newsletter together. There have also been some weeks where I’m on vacation and going “off the grid”.

    Luckily, Brian Gesiak, JP Simard, and Bas Broek have all stepped up numerous times to contribute and put together entire issues. It gets other people involved, it allows me to take a week off, and the community still gets their weekly dose of Swift news.

    For anyone that wants to contribute, everything you need to know is here. The entire process for publishing is open source. Just open an issue on GitHub for the week that you would like to write the newsletter and we can discuss!

    What advice would you give to any bloggers out there?

    When I look at successful blogs, I see programmers and writers writing about the things they know about — the things they are interested in and passionate about. Don’t write what you think people want to hear, write about what you know and what you like. If you do this, the result will be good articles that people want to read (perhaps with a bit of practice, too). So that’s step 1 — good content.

    Building and growing an audience is difficult, but I think it’s best for this to evolve organically. There’s no magic formula, so don’t try to force it — you’ll likely end up disappointed.

    One thing that’s effective for me is conferences. Speaking at a conference is really just an extension of my blog — a conference talk is like an “in-person” blog post. When you speak at a conference, you can tell people about your blog. If you aren’t speaking at conferences yet, you should try! Start by speaking at a local meetup, then try submitting abstracts to conferences.

    Love for Swift

    What’s the best feature you love in Swift 3.0 and how do you see the future of Swift going?

    The huge collection of API and syntax refinements has made a huge difference. Once you get over the painful migration, these improvements really make Swift a pleasure to use.

    Jesse is a Swift fan!

    Jesse is a Swift fan!

    As far as features, pretty much everything you need to know is on GitHub. But more broadly, I think Swift is on its way to being the dominant language on Apple’s platforms. It will take years, but eventually I think Objective-C will begin declining more rapidly. The day that Apple releases a pure Swift framework — that will be the turning point. I’m not sure when that will happen, but we know that Apple isn’t shy about abandoning old technologies.

    For other platforms, it’s difficult to predict. IBM is pushing for Swift on the server, and there’s now an official Sever APIs Project. Once server-side Swift matures, my bet is that it will take off. There’s so much enthusiasm for Swift on the server.

    As far as Android goes, I doubt Swift will ever be a first-class language. For that to happen, Google would need to invest in it and I don’t see that happening.

    You have now ported most of your open source libraries to Swift, how did you go about doing this?

    I migrated to Swift 3 in two distinct steps:

    1. I first migrated projects to Swift 2.3 and released major version updates.
    2. Then, I turned around and migrated to Swift 3 and released another major version update.

    I did this so anyone using my projects could stay on Swift 2.3 if needed while allowing the projects to continue moving forward. I made the decision not to maintain any older versions of Swift for any projects because I simply don’t have time.

    What advice would you give to somebody who wants to start building with Swift?

    I would definitely say do it! Personally, I think I write code faster and better with Swift.

    However, you should be aware that large apps have some large pain points. Uber, Lyft, LinkedIn and others have written posts and given talks about this, so check those out and decide if it’s worth the trade-off.

    Especially if you are starting with Swift 3, I think there’s a strong argument to use Swift despite the current shortcomings in tooling. The Swift team are aware and working hard on solving these problems.

    Where To Go From Here?

    And that concludes our Top App Dev Interview with Jesse Squires. Huge thanks to Jesse for sharing his work at Instagram, his love for Swift and finally running a successful blog.

    We hope you enjoyed this inspiring interview and if you’re thinking of starting your own blog or wanting to start talking at conferences to take Jesse’s advice to heart.

    If you are an app developer with a hit app or game in the top 100 in the App store, we’d love to hear from you. Please drop us a line anytime. If you have a request for any particular developer you’d like to hear from, please post your suggestion below!

    The post Instagram Dev, Swift Speaker & Swift Weekly Brief: A Top Dev Interview With Jesse Squires appeared first on Ray Wenderlich.

    Swift Algorithm Club: November Digest

    $
    0
    0

    SwiftAlgClub-Sept-Digest-feature

    The Swift Algorithm Club is an open source project to implement popular algorithms and data structures in Swift.

    We thought it would be useful to periodically give a status update with how things are going with the project.

    New SAC Team Member

    I’d like to officially announce our newest member of the SAC team, Vincent Ngo!

    Vincent Ngo is a writer, guitarist, and developer. After graduating from Virginia Tech, he continued to work with iOS development from an array of companies like Mindsense, IBM, and now Capital One. After work hours, he occasionally writes tutorials for raywenderlich.com.

    When Vincent is not at work, he enjoys coding for fun, playing video games, enjoying time with family and friends, and golfing. With hard work and dedication, he hopes to one day become a golfer good enough to participate in small tournaments.

    We’re excited to have Vincent on board, and he’ll be helping out with tutorials and repo management.

    Swift 3 Migration

    Our Swift 3 migration is coming to a close. So far, 52 of the 72 algorithms have been converted to Swift 3. Migration has generally been quite straightforward – it’s just the process of:

    • Making sure the playground compiles correctly
    • Making sure README.md file reflects the updated playground
    • Incorporate the new Swift API design guidelines in terms of naming of methods

    Want to help out? It’s a great way to learn about algorithms and Swift 3 at the same time. If so, check out our Github issue and sign up!

    Where To Go From Here?

    The Swift Algorithm Club is always looking for new members. Whether you’re here to learn or here to contribute, we’re happy to have you around.

    To learn more about the Swift Algorithm Club, check out our introductory article. We hope to see you at the club! :]

    The post Swift Algorithm Club: November Digest appeared first on Ray Wenderlich.

    AsyncDisplayKit 2.0 Tutorial: Getting Started

    $
    0
    0
    Learn how to achieve 60 FPS scrolling with AsyncDisplayKit.

    Learn how to achieve 60 FPS scrolling with AsyncDisplayKit.

    “Art is anything you can do well. Anything you can do with Quality.”
    —Robert M. Pirsig

    AsyncDisplayKit is a UI framework that was originally born from Facebook’s Paper app. It came as an answer to one of the core questions the Paper team faced: how can you keep the main thread as clear as possible?

    Nowadays, many apps have a user experience that relies heavily upon continuous gestures and physics based animations. At the very least, your UI is probably dependent on some form of scroll view.

    These types of user interfaces depend entirely on the main thread and are extremely sensitive to main thread stalls. A clogged main thread means dropped frames and an unpleasant user experience.

    Some of the big contributors to main thread work include:

    • Measurement and Layout: Things like -heightForRowAtIndexPath: or calling -sizeThatFits on a UILabel as well as the exponential cost of AutoLayout‘s constraint solver.
    • Image Decoding: Using a UIImage in an image view means the image data needs to be decoded first.
    • Drawing: Intricate text as well as manually drawing gradients and shadows.
    • Object Life Cycle: Creating, manipulating and destroying system objects (ie. creating a UIView).

    When used correctly, AsyncDisplayKit allows you to perform all measurement, layout and rendering asynchronously by default. Without any extra optimization an app can experience roughly an order of magnitude reduction in the amount of work done on the main thread.


    In addition to these performance wins, modern AsyncDisplayKit offers an impressive set of developer conveniences that allow implementing complex, sophisticated interfaces with a minimum of code.

    In this two part AsyncDisplayKit 2.0 tutorial, you’ll learn all the essentials to build a useful and dynamic application with ASDK. In part one, you’ll learn some big picture ideas you can use when architecting an app. In part two, you’ll learn how to build your own node subclass as well as how to use ASDK’s powerful layout engine. In order to complete this tutorial you will need Xcode 7.3 and familiarity with Objective-C.

    Disclaimer: ASDK is incompatible with both Interface Builder and AutoLayout, so you won’t be using them in this tutorial. Although ASDK fully supports Swift (a distinction from ComponentKit), many of its users are still writing Objective-C. At the moment, the majority of the top 100 free apps don’t include any Swift at all (at least 6 use ASDK). For these reasons, this series will focus on Objective-C. That being said, we’ve included a Swift version of the sample project in case you hate staples.

    Getting Started

    To begin, go ahead and download the starter project.

    The project uses CocoaPods to pull in AsyncDisplayKit. So, in usual CocoaPods style, go ahead and open RainforestStarter.xcworkspace but NOT RainforestStarter.xcodeproj.

    Note: A network connection is required to work through this tutorial.

    Build and run to see an app consisting of one UITableView containing a list of animals. If you look at the code in AnimalTableController you’ll see that it’s a normal UITableViewController class you’ve probably seen plenty of times.

    Note: Make sure to run the code in this tutorial on a physical device instead of in the simulator.

    Scroll through the animals and notice the number of frames that are being dropped. You don’t need to fire up Instruments to be able to see that this app needs some help in the performance department.

    LaggyScrolling

    You can fix that, through the power of AsyncDisplayKit.

    Introducing ASDisplayNode

    ASDisplayNode is the core class of ASDK and is, at its heart, just an MVC “view” object in the same way as a UIView or CALayer. The best way to think about a node is by thinking about the relationship between UIViews and CALayers that you should already be familiar with.

    Remember that everything onscreen in an iOS app is represented via a CALayer object. UIViews create and own a backing CALayer to which they add touch handling and other functionality. UIViews themselves are not a CALayer subclass. Instead, they wrap around a layer object, extending its functionality.

    view-layer

    This abstraction is extended in the case of ASDisplayNode: you can think of them as wrapping a view, just like a view wraps a layer.

    What nodes bring to the table over a regular view is the fact that they can be created and configured on background queues and are concurrently rendered by default.

    node-view-layer

    Luckily, the API for dealing with nodes should be incredibly familiar to anyone who’s used UIViews or CALayers. All the view properties you would normally use are available on the equivalent node class. You can even access the underlying view or layer itself — just as you can access the .layer of a UIView.

    The Node Containers

    While nodes themselves provide the possibility of vast performance improvements, the real magic happens when they’re used in conjunction with one of the four container classes.

    These classes include:

    • ASViewController: A UIViewController subclass that allows you to provide the node you want to be managed.
    • ASCollectionNode and ASTableNode: Node equivalents to UICollectionView and UITableView, a subclass of which is actually maintained under the hood.
    • ASPagerNode: A subclass of ASCollectionNode which offers great swiping performance compared to UIKit’s UIPageViewController.

    ragecomic

    Fair enough, but the real magic comes from the ASRangeController each of these classes uses to influence the behavior of the contained nodes. For now, just trust me and keep that in the back of your head for later.

    Converting the TableView

    The first thing you’ll do is to convert the current table view into a table node. Doing this is relatively straightforward.

    Replacing tableView with tableNode

    First, navigate to AnimalTableController.m. Add the following line below the other imports in this class:

    #import <AsyncDisplayKit/AsyncDisplayKit.h>

    This imports ASDK in order to use the framework.

    Then, go ahead and replace the following property declaration of tableView:

    @property (strong, nonatomic) UITableView *tableView;

    with the following tableNode:

    @property (strong, nonatomic) ASTableNode *tableNode;

    This will cause a lot of code in this class to break, but do not panic!

    butBut

    Seriously, don’t worry. These errors and warnings will serve as your guide in the task of converting what you currently have into what you really want.

    The errors in -viewDidLoad are, of course, to do with the fact that the tableView doesn’t exist anymore. I’m not going to make you go through and change all the instances of tableView to tableNode (I mean, find and replace isn’t that hard so feel free to) but if you did you’d see that:

    1. You should be assigning an ASTableNode to the property.
    2. A table node doesn’t have a method called -registerClass:forCellReuseIdentifier:.
    3. You can’t add a node as a subview.

    At this point you should just replace -viewDidLoad with the following:

    - (void)viewDidLoad {
      [super viewDidLoad];
     
      [self.view addSubnode:self.tableNode];
      [self applyStyle];
    }

    The interesting thing to note here is that you’re calling -addSubnode: on a UIView. This method has been added to all UIViews via a category, and is exactly equivalent to:

    [self.view addSubview:self.tableNode.view];

    Next, fix -viewWillLayoutSubviews by replacing that method definition with the following:

    - (void)viewWillLayoutSubviews {
      [super viewWillLayoutSubviews];
     
      self.tableNode.frame = self.view.bounds;
    }

    All this does is replace self.tableView with self.tableNode to set the table’s frame.

    Next, find the -applyStyle method and replace the implementation with the following:

    - (void)applyStyle {
      self.view.backgroundColor = [UIColor blackColor];
      self.tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone;
    }

    The line that sets the table’s separatorStyle is the only line that changed. Notice how the table node’s view property is accessed in order to set the table’s separatorStyle. ASTableNode does not expose all the properties of UITableView, so you have to access the table node’s underlying UITableView instance in order to change UITableView specific properties.

    Then, add the following line at the very beginning of -initWithAnimals:

    _tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];

    and add the following at the end, before the initializer’s return statement:

    [self wireDelegation];

    This initializes AnimalTableController with a table node and calls -wireDelegation to wire up the table node’s delegates.

    Setting the Table Node’s Data Source & Delegate

    Just like UITableView, ASTableNode uses a data source and delegate to get information about itself. Table node’s ASTableDataSource and ASTableDelegate protocols are very similar to UITableViewDataSource and UITableViewDelegate. As a matter of fact, they define some of the exact same methods such as -tableNode:numberOfRowsInSection:. The two sets of protocols don’t match up perfectly because ASTableNode behaves a bit differently than UITableView.

    Find -wireDelegation and replace tableView with tableNode in the implementation:

    - (void)wireDelegation {
      self.tableNode.dataSource = self;
      self.tableNode.delegate = self;
    }

    Now, you’ll be told that AnimalTableController doesn’t actually conform to the correct protocol. Currently, AnimalTableController conforms to to UITableViewDataSource and UITableViewDelegate. In the following sections you will conform to and implement each of these protocols so that the view controller’s table node can function.

    Conforming to ASTableDataSource

    Towards the top of AnimalTableController.m, find the following DataSource category interface declaration:

    @interface AnimalTableController (DataSource)<UITableViewDataSource>
    @end

    and replace UITableViewDataSource with ASTableDataSource:

    @interface AnimalTableController (DataSource)<ASTableDataSource>
    @end

    Now that AnimalTableController declares conformance to ASTableDataSource, it’s time to make it so.

    Navigate toward the bottom of AnimalTableController.m and find the implementation of the DataSource category.

    First, change the UITableViewDataSource method -tableView:numberOfRowsInSection: to the ASTableDataSource version by replacing it with the following.

    - (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section {
      return self.animals.count;
    }

    Next, ASTableNodes expect their cells to be returned in a different way than a UITableView would. To accommodate the new paradigm replace -tableView:cellForRowAtIndexPath: with the following method:

    //1
    - (ASCellNodeBlock)tableNode:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath {
      //2
      RainforestCardInfo *animal = self.animals[indexPath.row];
     
      //3
      return ^{
        //4
        CardNode *cardNode = [[CardNode alloc] initWithAnimal:animal];
     
        //You'll add something extra here later...
        return cardNode;
      };
    }

    Let’s review this section by section:

    1. An ASCellNode is the ASDK equivalent to a UITableViewCell or a UICollectionViewCell. The more important thing to notice is that this method returns an ASCellNodeBlock. This is because an ASTableNode maintains all of its cells internally and by giving it a block for each index path, it can concurrently initialize all of its cells when it’s ready.
    2. The first thing you do is grab a reference to the data model needed to populate this cell. This is a very important pattern to take note of. You grab the data and then capture it inside the following block. The indexPath shouldn’t be used inside the block, in case the data changes before the block is run.
    3. You then return a block whose return value must be an ASCellNode.
    4. There is no need to worry about cell reuse so just chill and initialize a cell the easy way. You may notice that you’re returning a CardNode now instead of a CardCell.

    This brings me to an important point. As you may have gathered, there is no cell reuse when using ASDK. Alright, maybe I already basically said that twice, but it’s a good thing to keep in mind. Feel free to go to the top of the class and delete

    static NSString *kCellReuseIdentifier = @"CellReuseIdentifier";

    You won’t be needing it anymore.

    Maybe take a second to mull that over. You never have to worry about -prepareForReuse again…

    Conforming to ASTableDelegate

    Towards the top of AnimalTableController.m, find the following Delegate category interface declaration:

    @interface AnimalTableController (Delegate)<UITableViewDelegate>
    @end

    and replace UITableViewDelegate with ASTableDelegate:

    @interface AnimalTableController (Delegate)<ASTableDelegate>
    @end

    Now that AnimalTableController declares conformance to ASTableDelegate, it’s time to handle the implementation. Navigate towards the bottom of AnimalTableController.m and find the implementation of this Delegate category.

    As I’m sure you’re aware, with a UITableView you usually need to, at least, provide an implementation of -tableView:heightForRowAtIndexPath:. This is because, with UIKit, the height of each cell is calculated and returned by the table’s delegate.

    ASTableDelegate lacks -tableView:heightForRowAtIndexPath:. In ASDK, all ASCellNodes are responsible for determining their own size. Instead of being providing a static height, you can optionally define a minimum and maximum size for your cells. In this case, you want each cell to at least be as tall as 2/3rds of the screen.

    Don’t worry about this too much right now; it’s covered in detail in part two of this series.

    For now, just replace -tableView:heightForRowAtIndexPath: with:

    - (ASSizeRange)tableView:(ASTableView *)tableNode
      constrainedSizeForRowAtIndexPath:(NSIndexPath *)indexPath {
      CGFloat width = [UIScreen mainScreen].bounds.size.width;
      CGSize min = CGSizeMake(width, ([UIScreen mainScreen].bounds.size.height/3) * 2);
      CGSize max = CGSizeMake(width, INFINITY);
      return ASSizeRangeMake(min, max);
    }

    After all your hard work, go ahead and build and run to see what you have.

    AfterTableNodeBeforePager

    That is one smooth table! Once you’ve composed yourself a little, get ready to make it even better.

    Infinite Scrolling with Batch Fetching

    In most apps, the server has more data points available than the number of cells you’d want to show in your average table. This means that darn near every app you work on will have some mechanism set up to load another batch of objects from the server as the user approaches the end of the current data set.

    Many times, this is handled by manually observing the content offset in the scroll view delegate method -scrollViewDidScroll:. With ASDK, there is a more declarative way of doing things. Instead, you can describe how many pages in advance you’d like to load new content.

    The first thing you’ll do, is uncomment the helper methods that have been included. Go to the end of AnimalTableController.m and uncomment the two methods in the Helpers category. You can think of -retrieveNextPageWithCompletion: as your networking call, while -insertNewRowsInTableNode: is a pretty standard method for adding new elements to a table.

    Next, add the following line to -viewDidLoad:.

    self.tableNode.view.leadingScreensForBatching = 1.0;  // overriding default of 2.0

    Setting leadingScreensForBatching to 1.0 means that you want new batches to be fetched whenever the user has scrolled to the point where only 1 screenful of content is left in the table before they would reach the end.

    Next, add the following method to the Delegate category implementation:

    - (BOOL)shouldBatchFetchForTableNode:(ASTableNode *)tableNode {
      return YES;
    }

    This method is used to tell the table whether or not it should keep making requests for new batches after this one. If you know you’ve reached the end of your API’s data, return NO and no more requests will be made.

    Since you really do want this table to scroll forever, just return YES to ensure new batches will always be requested.

    Next, also add:

    - (void)tableNode:(ASTableNode *)tableNode willBeginBatchFetchWithContext:(ASBatchContext *)context {
      //1
      [self retrieveNextPageWithCompletion:^(NSArray *animals) {
        //2
        [self insertNewRowsInTableNode:animals];
     
        //3
        [context completeBatchFetching:YES];
      }];
    }

    This method is called when the user has neared the end of the table and the table has received a YES from -shouldBatchFetchForTableNode:.

    Let’s review this section by section:

    1. First, you make a request for the next batch of animals to show. Usually this is an array of objects coming back from an API.
    2. On completion, update the table with the newly downloaded data.
    3. Finally, make sure to call -completeBatchFetching: with YES when you’re done. New batch fetching requests won’t be made until this one has been completed.

    Build, run, and just start swiping. Don’t stop until you don’t care to see another bird. They are infinite.

    InfiniteScrollingGif

    Intelligent Preloading

    Have you ever worked on an app where you decided to load content in advance in some kind of scroll view or page view controller? Maybe you were working on a full-screen image gallery and you decided you always wanted the next few images to be loaded and waiting so your users rarely saw a placeholder.

    iThinkIveGotThis

    When you do work on a system like this, you soon realize there’s a lot to think about.

    • How much memory are you taking up?
    • How far in advance should you be loading content?
    • When do you decide to dump what you have in response to user interaction?

    And this gets quite a lot more complex when you factor in multiple dimensions of content. Do you have a page view controller with a collection view inside of each of the view controllers? Now you need to think of how you’re going to dynamically load content in both directions… Also, go ahead and tune that for each device you’re supporting. K, thanks.

    officespaceboss

    Remember how I told you to to keep that ASRangeController thing on the back burner of your mind? Well move it to the front burner!

    Within each of the container classes there is a concept of the interface state for each of the contained nodes. At any given time, a node can be in any combination of:

    preloadingRanges-small

    • Preload Range: Usually the furthest range out from being visible. This is when content for each subnode in a cell, such as an ASNetworkImageNode, should be loaded from some external source; an API or a local cache for example. This is in contrast to batch fetching which should be used to fetch model objects representing cells themselves.
    • Display Range: Here, display tasks such as text drawing and image decoding take place.
    • Visible Range: At this point, the node is onscreen by at least one pixel.

    These ranges also work on the metric of “screenfuls” and can be easily tuned using the ASRangeTuningParameters property.

    For example, you’re using an ASNetworkImageNode to display the image in each page of the gallery. Each one will request data from the network when it enters the Preload Range and decode the image it has retrieved when it enters the Display Range.

    In general, you don’t have to think too hard about these ranges if you don’t want to. The built in components, such as ASNetworkImageNode and ASTextNode, take full advantage of them which means you will see huge benefits by default.

    Note: One thing that may not be obvious is that these ranges don’t stack. Instead they overlap and converge on the visible range. If you set the display and prefetch both to one screen, they will happen at exactly the same time. The data usually needs to be present for display to be possible, so usually the prefetch range should be a little larger so nodes will be ready to start the display process when they make it to that range.

    In general, the leading side of the range is larger than the trailing side. When the user changes their scroll direction, the sizes of the ranges reverse as well in order to favor the content the user is actually moving toward.

    Node Interface State Callbacks

    You’re probably wondering how exactly these ranges work right? I’m glad you asked.

    Every node in the system has an interfaceState property which is a “bitfield” (NS_OPTION) type ASInterfaceState. As the ASCellNode moves through a scroll view managed by an ASRangeController, each subnode has its interfaceState property updated accordingly. This means that even the deepest nodes in the tree can respond to interfaceState changes.

    Luckily, it’s rarely necessary to fiddle with the bits of a node’s interfaceState directly. More often, you’ll just want to react to a node changing to or from a certain state. That’s where the interface state callbacks come in.

    Naming Nodes

    In order to see a node move through the various states, it is useful to give it a name. This way, you’ll be able to watch as each node loads its data, displays its content, comes on-screen and then does the whole thing in reverse as it leaves.

    Go back to -tableNode:nodeBlockForRowAtIndexPath:, and find the comment that says:

    //You'll add something extra here later...

    Right below it, add the following line to give each cell a debugName.

    cardNode.debugName = [NSString stringWithFormat:@"cell %zd", indexPath.row];

    Now you’ll be able to track the cells’ progression through the ranges.

    Observing the Cells

    Navigate to CardNode_InterfaceCallbacks.m. Here you’ll find six methods you can use to track a node’s progress through the various ranges. Uncomment them, and then build and run. Make sure your console in Xcode is visible and then scroll slowly. As you do, watch as the various cells react to their changing states.

    console

    Note: In most cases, the only ASInterfaceState change method you’ll care about is -didEnterVisibleState or -didExitVisibleState. That said, a lot of work is going on under the hood for you. To check out what you can do by integrating with the Preload and Display states, take a look at the code in ASNetworkImageNode. All network image nodes will automatically fetch and decode their content, as well as free up memory, without you needing to lift a finger.

    (Intelligent Preloading)2

    In the 2.0 release, the concept of intelligently preloading content in multiple directions was introduced. Say you have a vertically scrolling table view, and at some point a cell comes onscreen that contains a horizontal collection view.

    proaldGif^2

    Though this collection is now technically in the visible region, you wouldn’t want to load the entire collection up front. Instead, both scroll views have their own ASRangeController complete with separately configurable range tuning parameters.

    Entering the Second Dimension

    Now that you have completed AnimalTableController, you’re able to use it as a page in an ASPagerNode.

    The view controller you’ll use to contain this pager is already in the project so the first thing you need to do is navigate to AppDelegate.m.

    Find -installRootViewController and replace:

    AnimalTableController *vc = [[AnimalTableController alloc]
                                  initWithAnimals:[RainforestCardInfo allAnimals]];

    with:

    AnimalPagerController *vc = [[AnimalPagerController alloc] init];

    Then, go into AnimalPagerController.m and add the following lines to the initializer right before the return statement. All you need to do is create a new pager and set its dataSource to be this view controller.

    _pagerNode = [[ASPagerNode alloc] init];
    _pagerNode.dataSource = self;

    The pager node is actually a subclass of an ASCollectionNode preconfigured to be used in the same way you’d use a UIPageViewController. The nice thing about this is that the API is actually quite a bit simpler to think about than UIPageViewController‘s.

    The next thing you have to do is to implement the pager’s data source methods. Navigate to the ASPagerDataSource category implementation at the bottom of this file.

    First, tell the pager that its number of pages is equal to the number of animal arrays, in this case, three by replacing the existing -numberOfPagesInPagerNode:.

    - (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode {
      return self.animals.count;
    }

    Then, you need to implement -pagerNode:nodeAtIndex:, similar to the node block data source method you implemented for the ASTableNode earlier.

    - (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index {
      //1
      CGSize pagerNodeSize = pagerNode.bounds.size;
      NSArray *animals = self.animals[index];
     
      //2
      ASCellNode *node = [[ASCellNode alloc] initWithViewControllerBlock:^{
        return [[AnimalTableController alloc] initWithAnimals:animals];
      } didLoadBlock:nil];
     
      return node;
    }

    Let’s review this section by section:

    1. Although this version isn’t block-based, it’s good practice to grab your data model first.
    2. This time, you’re using the powerful -initWithViewControllerBlock: initializer. All you need to do is return a block that returns the table node controller you fixed up earlier and the managed view will automatically be used as the view for each page. Pretty cool if you ask me. ;]

    Once you’ve added this method you’ll have a fully functioning pager whose cells are generated from the tableNodeController you created earlier. This comes fully stocked with two dimensional preloading based on the vertical and horizontal scrolling performed by the user!

    AfterASDKGif

    Where To Go From Here?

    To see the completed project for this AsyncDisplayKit 2.0 tutorial, download it here. If you’re wanting to see all this in Swift, we’ve got that too.

    When you’re ready, move on to part 2 of this project to learn about the powerful new layout system introduced with AsyncDisplayKit 2.0.

    If you’d rather do a little more research before moving on, you can check out AsyncDisplayKit’s home page and read through some of the documentation. Scott Goodson (the original author of AsyncDisplayKit) also has a few talks you may be interested in, listed in chronological order on the AsyncDisplayKit.org Resources page.

    You may also be interested in the Building Paper event. Although none of this was open sourced at that time, and a lot has changed, it’s pretty interesting to see where it all started.

    Lastly, as part of the AsyncDisplayKit community’s legendary reputation for welcoming newcomers, there is a public Slack channel where anyone is invited to come and ask questions!

    Hopefully you enjoyed this tutorial, let us know if you have any questions or comments by joining the forum discussion below!

    The post AsyncDisplayKit 2.0 Tutorial: Getting Started appeared first on Ray Wenderlich.

    Unity Games by Tutorials Updated for Unity 5.5

    $
    0
    0

    Unitygames-feature

    A major new update to Unity – version 5.5 – came out last week.

    And good news – we’ve been hard at work updating our popular book Unity Games by Tutorials for Unity 5.5, and the new version is available today!

    Here are some of the things we’ve updated in this version of the book:

    • Unity 5.5 UI updates throughout
    • Project wizard updates
    • Animation window updates
    • Namespace updates
    • GameObject selection outline updates
    • Web GL publishing updates
    • Starter and final projects now support Unity 5.5
    • …and more!

    It took several late nights of coding, testing, rewriting, and lots and lots of caffeine in various forms, but we wanted to get you this update as fast as we could. :]

    A completely updated book in six days? No sweat! (Okay, we lied, lots of sweat. And tears. And coffee.)

    A completely updated book in six days? No sweat! (Okay, we lied, lots of sweat. And tears. And coffee.)

    It’s a huge achievement for us, and we’re happy to share it with you. Read on to see how to get your updated copy!

    Play Bobblehead Wars Online!

    As an extra-special treat to celebrate this release, author Brian Moakley has built a Web GL version of Bobblehead Wars, the twin-stick shooter game you’ll create in Section 1.

    Have a go at defending yourself against waves of marauding aliens, intent on snacking on your brave space marine. Arrow keys (or WASD keys) to move, and mouse to turn and shoot:


    (Click inside the game area if the arrow keys don’t seem to move the space marine.)

    We show you how to build this game step-by-step in the book; along with a first-person shooter, a 2D platformer, and a tower defense game – with VR support!

    If you’re looking to learn how to make cross-platform games with the game engine used to make City Skylines, Hearthstone, the Long Dark, and more – this is the book for you.

    How to Get the Update

    This free update is available today for all Unity Games by Tutorials PDF customers, as our way of saying “thanks” for supporting the book and the site.

    • If you’ve already bought the Unity Games by Tutorials PDF, you can download the updated book immediately on your My Loot page.
    • If you don’t have Unity Games by Tutorials yet, you can grab your own updated copy in our store.

    We hope you enjoy this version of the book, fully updated for Unity 5.5. And a big thanks to the book team that managed to turn this around in an amazingly short time!

    The post Unity Games by Tutorials Updated for Unity 5.5 appeared first on Ray Wenderlich.

    Updated Course: iOS Concurrency with GCD & Operations

    $
    0
    0

    X_post-Feature-Conc-GCD-NSO

    Today I’m happy to announce my newly updated course on raywenderlich.com: iOS Concurrency with GCD & Operations!

    Concurrency is a fancy way of saying “running more than one task at the same time”. Concurrency is used quite frequently on iOS devices so you can run tasks in the background (like downloading or processing data) while you keep your user interface responsive.

    GCD (or Grand Central Dispatch) and Operations (formerly called NSOperation) are the APIs you use in iOS to manage concurrent tasks (as opposed to working with threads directly).

    This is a course for intermediate iOS developers who are looking to master using GCD and Operation to run concurrent tasks in their apps. It’s particularly beneficial for folks who have used GCD and Operations a bit but want to take their knowledge to a deeper level.

    It’s also fully up-to-date with Swift 3, Xcode 8, and iOS 10!

    Here’s an overview of what’s inside:

    Introduction

    Video 1: Introduction. You’ll get overview of what concurrency is, the difference between GCD and Operations and when to use each, and take a tour of some classic challenges with concurrency, such as race conditions, priority inversion, and deadlock.

    2-Terminology

    Video 2: Terminology. You’ll learn the terms you’ll be using in the rest of the series, such as synch vs. asynchronous, serial queue vs. concurrent queue, and you’ll learn how to dispatch your first tasks to GCD queues in a Swift playground.

    3-SimpleUseCases

    Video 3: Simple Use Cases. Next you’ll take a look at some simple GCD use cases, such as running a chain of tasks, a collection of independent but similar tasks, and how to make synchronous tasks asynchronous.

    4-DispatchGroups

    Video 4: Dispatch Groups. Learn the power of GCD dispatch groups, which allow you to respond to the completion of a collection of GCD tasks.

    5-TiltShiftOperation

    Video 5: Operations. Next you’ll go to a higher level of abstraction and use how to use Operation, is a class that allows you to wrap up a unit of work, into a package you can execute at some time in the future. Along the way, you’ll create a cool tilt-shift image filtering operation!

    6-OperationQueues

    Video 6: OperationQueue. Learn how to use OperationQueue to gain more power and control over the scheduling and execution of Operations.

    7-AsyncOperations

    Video 7: AsyncOperation. Learn how to use an Operation to wrap an asynchronous function such as a network call into a reusable object.

    8-Dependencies

    Video 8: Dependencies. Learn how to create dependencies between different Operations, and how to pass data from one Operation to another.

    9-Cancellation

    Video 9: Cancelling Tasks. Learn how to cancel an Operation while it’s running.

    10-OperationsInPractice

    Video 10: Operations in Practice. Pull together all the concurrency knowledge you’ve learned so far in this series to improve the scrolling performance of a table view in a realistic app.

    11-GeneralAdvice

    Video 11: Concurrency Solutions. Learn how to create thread-safe objects to prevent inconsistent state, and how to avoid other concurrency problems.

    Where To Go From Here?

    Want to check out the course? You can watch the introduction for free!

    The rest of the course is for raywenderlich.com subscribers only. Here’s how you can get access:

    • If you are a raywenderlich.com subscriber: The entire course is complete and available today You can check out the first part here.
    • If you are not subscribed yet: What are you waiting for – subscribe now to get access to our updated iOS Concurrency course and our entire catalog of over 500 videos.

    We hope you enjoy, and stay tuned for more new Swift 3 courses and updates to come! :]

    The post Updated Course: iOS Concurrency with GCD & Operations appeared first on Ray Wenderlich.


    Open Call for Authors on the macOS Team

    $
    0
    0

    OpenCall-OSX-feature

    The macOS team has over 20 free macOS tutorials, and the list continues to expand.

    We’re looking to grow the team so that we can provide the macOS development community with top notch tutorials. This is also an opportunity that could lead to involvement in a new macOS book.

    Joining our team is a great way to learn and improve – not to mention, getting paid for it!

    If this sounds interesting, keep reading to find out what’s involved and how to apply.

    Why Join Our Team?

    Here are the top 5 reasons to join the macOS team:

    1. Learning. You’ll always be learning something new — and will have fun doing it! You’ll become a better developer, writer and person. The best part… you’ll make a lot of new friends along the way.
    2. Money! Get paid to learn! We offer the highest rates in the industry.
    3. Special Opportunities. Members of the team get access to special opportunities such as contributing to our books and products, speaking at our conference, being a guest on our podcast, working on team projects and much more.
    4. You’ll Make a Difference. We get emails every day about how our tutorials help our readers make their first game, improve their skills and achieve their dreams. This means a lot to us, and makes all the hard work worth it!
    5. Free Stuff! And as a final bonus, by joining the team you’ll get a lot of free stuff! You’ll get a free copy of all of the products we sell on the site — over $1,000 in value!

    Aww Yeah!

    Requirements and How to Apply

    Here are the requirements:

    • You must be an experienced macOS developer.
    • You should be a great writer with fluent English writing skills.
    • You should be comfortable learning brand new topics that you’ve never done before.
    • You should have a strong work ethic — this will be a significant time commitment and is not easy.

    To apply, send me an e-mail. Be sure to include the following information:

    • Please tell me a little bit about yourself and your experience with macOS development.
    • What is the best app or game you’ve ever worked on in macOS? [Please include link]
    • Please link to any examples of technical writing you’ve done in the past.
    • Please include links to: your GitHub account and your Twitter account.

    If your application looks promising, we’ll send you a tryout to gauge your writing and/or editing skills.

    If you pass the tryout, you’re in!

    What Are You Waiting For?

    If this opportunity interests you, go on and send me an e-mail! I look forward to creating some great tutorials with you. :]

    The post Open Call for Authors on the macOS Team appeared first on Ray Wenderlich.

    Introducing Protocol-Oriented Programming in Swift 3

    $
    0
    0
    ProtocolOriented-feature

    Protocol-Oriented Programming will help you fly!

    Update Note: This tutorial has been updated to Swift 3.0 by Niv Yahel. The original tutorial was written by Erik Kerber.

    Imagine you’re developing a racing game. You can drive a car, ride a motorcycle, or even fly a plane. A common approach to creating this type of application is by using object oriented design, encapsulating all of the logic inside of an object that gets inherited to all of those that share similarity.

    This design approach works, but does come with some drawbacks. For example, if you add the ability to create machines that also require gas, birds that fly in the background, or anything else that may want to share game logic, there isn’t a good way to separate the functional components of vehicles into something reusable.

    This scenario is where protocols really shine.

    Swift has always let you specify interface guarantees on existing class, struct and enum types using protocols. This lets you interact with them generically. Swift 2 introduced a way to extend protocols and provide default implementations. Finally, Swift 3 improves operator conformance and uses these improvements for the new numeric protocols in the standard library.

    Protocol are extremely powerful and can transform the way you write code. In this tutorial, you’ll explore the ways you can create and use protocols, as well as use protocol-oriented programming patterns to make your code more extensible.

    You’ll also see how the Swift team was able to use protocol extensions to improve the Swift standard library itself, and how it impacts the code you write.

    Getting Started

    Begin by creating a new playground. In Xcode, select File\New\Playground… and name the playground SwiftProtocols. You can select any platform, since all the code in this tutorial is platform-agnostic. Click Next to choose where you would like to save it, and finally click Create.

    Once your new playground is open, add the following code to it:

    protocol Bird {
      var name: String { get }
      var canFly: Bool { get }
    }
     
    protocol Flyable {
      var airspeedVelocity: Double { get }
    }

    This defines a simple protocol Bird with properties name and canFly, as well as a Flyable protocol which defines airspeedVelocity.

    In a pre-protocol world, you might have started with Flyable as a base class and then relied on object inheritance to define Bird as well as other things that fly, such as airplanes. Note that here, everything is starting out as a protocol! This allows you to encapsulate the functional concept in a way that doesn’t require a base class.

    You’ll see how this makes the entire system more flexible when you start to define actual types next.

    Defining Protocol-Conforming Types

    Add the following struct definition to the bottom of the playground:

    struct FlappyBird: Bird, Flyable {
      let name: String
      let flappyAmplitude: Double
      let flappyFrequency: Double
      let canFly = true
     
      var airspeedVelocity: Double {
        return 3 * flappyFrequency * flappyAmplitude
      }
    }

    This defines a new struct FlappyBird, which conforms to both the Bird and Flyable protocols. Its airspeedVelocity is calculated as a function of flappyFrequency and flappyAmplitude. Being flappy, it returns true for canFly. :]

    Next, add the following two struct definitions to the bottom of the playground:

    struct Penguin: Bird {
      let name: String
      let canFly = false
    }
     
    struct SwiftBird: Bird, Flyable {
      var name: String { return "Swift \(version)" }
      let version: Double
      let canFly = true
     
      // Swift is FASTER every version!
      var airspeedVelocity: Double { return version * 1000.0 }
    }

    A Penguin is a Bird, but cannot fly. A-ha — it’s a good thing you didn’t take the inheritance approach, and make all birds flyable after all! Using protocols allows you to define functional components and have any relevant object conform to them.

    Already you can see some redundancies. Every type of Bird has to declare whether it canFly or not, even though there’s already a notion of Flyable in your system.

    Extending Protocols With Default Implementations

    With protocol extensions, you can define default behavior for a protocol. Add the following just below the Bird protocol definition:

    extension Bird {
      // Flyable birds can fly!
      var canFly: Bool { return self is Flyable }
    }

    This defines an extension on Bird that sets the default behavior for canFly to return true whenever the type is also Flyable. In other words, any Flyable bird no longer needs to explicitly declare so!

    protocols-extend

    Delete the let canFly = ... from FlappyBird, SwiftBird and Penguin struct declarations. You’ll see that the playground successfully builds since the protocol extension now handles that requirement for you.

    Why Not Base Classes?

    Protocol extensions and default implementations may seem similar to using a base class or even abstract classes in other languages, but they offer a few key advantages in Swift:

    • Because types can conform to more than one protocol, they can be decorated with default behaviors from multiple protocols. Unlike multiple inheritance of classes which some programming languages support, protocol extensions do not introduce any additional state.
    • Protocols can be adopted by classes, structs and enums. Base classes and inheritance are restricted to class types.

    In other words, protocol extensions provide the ability to define default behavior for value types and not just classes.

    You’ve already seen this in action with a struct. Next, add the following enum definition to the end of the playground:

    enum UnladenSwallow: Bird, Flyable {
      case african
      case european
      case unknown
     
      var name: String {
        switch self {
          case .african:
            return "African"
          case .european:
            return "European"
          case .unknown:
            return "What do you mean? African or European?"
        }
      }
     
      var airspeedVelocity: Double {
        switch self {
        case .african:
          return 10.0
        case .european:
          return 9.9
        case .unknown:
          fatalError("You are thrown from the bridge of death!")
        }
      }
    }

    As with any other value type, all you need to do is define the correct properties so UnladenSwallow conforms to the two protocols. Because it conforms to both Bird and Flyable. It also gets the default implementation for canFly!

    Did you really think this tutorial involving airspeedVelocity wouldn’t include a Monty Python reference? :]

    Overriding Default Behavior

    Your UnladenSwallow type automatically got an implementation for canFly by virtue of conforming to the Bird protocol. However, you really want UnladenSwallow.unknown to return false for canFly. Is it possible to override the default implementation? Yes, it is. Add this to the end of your playground.

    extension UnladenSwallow {
      var canFly: Bool {
        return self != .unknown
      }
    }

    Now only .african and .european will return true for canFly. Test it out by adding the following to the end of your playground:

    UnladenSwallow.unknown.canFly  // false
    UnladenSwallow.african.canFly  // true
    Penguin(name: "King Penguin").canFly  // false

    In this way, it is possible to override properties and methods much like you can with virtual methods in object oriented programming.

    Extending Protocols

    You can utilize protocols from the standard library and also define default behaviors.

    Modify the Bird protocol declaration to conform to the CustomStringConvertible protocol:

    protocol Bird: CustomStringConvertible {

    Conforming to CustomStringConvertible means your type needs to have a description property so it acts like a String. Does that mean you now have to add this property to every current and future Bird type?

    Of course, there’s an easier way with protocol extensions. Add the code underneath the Bird definition:

    extension CustomStringConvertible where Self: Bird {
      var description: String {
        return canFly ? "I can fly" : "Guess I’ll just sit here :["
      }
    }

    This extension will make the canFly property represent each Bird type’s description value.

    To try it out, add the following to the bottom of the playground:

    UnladenSwallow.african

    You should see “I can fly!” appear in the assistant editor. But more notably, you just extended your own protocol!

    Effects on the Swift Standard Library

    You’ve seen how protocol extensions are a great way to customize and extend the capabilities. What may surprise you is how the Swift team was able to use protocols to improve the way the Swift standard library is written as well.

    Add the following code to the end of your playground:

    let numbers = [10,20,30,40,50,60]
    let slice = numbers[1...3]
    let reversedSlice = slice.reversed()
     
    let answer = reversedSlice.map { $0 * 10 }
    print(answer)

    This should look pretty straightforward, and you might even be able to guess the answer that is printed. What might be surprising are the types involved. slice, for example, is not an Array of integers but an ArraySlice<Int>. This special wrapper type acts as a view into the original array and avoids costly memory allocations that can quickly add up. Similarly, reversedSlice is actually a ReversedRandomAccessCollection<ArraySlice<Int>> which is again just a wrapper type view into the original array.

    secrets

    Fortunately, the geniuses developing the standard library defined the map method as an extension to the Sequence protocol and all of the collection wrappers (of which there are dozens) to conform to this protocol. This makes it possible to call map on Array just as easily as it is ReversedRandomAccessCollection and not notice the difference. You will borrow this important design pattern shortly.

    Off to the Races

    So far you defined several Bird conforming types. Now add something totally different to the end of your playground.

    class Motorcycle {
      init(name: String) {
        self.name = name
        speed = 200
      }
      var name: String
      var speed: Double
    }

    This class that has nothing to do with birds or flying things you have defined so far. But you want to race motorcycles as well as penguins. Time to bring all of the pieces together.

    Bringing it Together

    It is time to unify all of these disparate types with a common protocol for racing. You can do this with out even going back and touching the original model definitions. The fancy term for this is retroactive modeling. Just add the following to your playground:

    protocol Racer {
      var speed: Double { get }  // speed is the only thing racers care about
    }
     
    extension FlappyBird: Racer {
      var speed: Double {
        return airspeedVelocity
      }
    }
     
    extension SwiftBird: Racer {
      var speed: Double {
        return airspeedVelocity
      }
    }
     
    extension Penguin: Racer {
      var speed: Double {
        return 42  // full waddle speed
      }
    }
     
    extension UnladenSwallow: Racer {
      var speed: Double {
        return canFly ? airspeedVelocity : 0
      }
    }
     
    extension Motorcycle: Racer {}
     
    let racers: [Racer] =
      [UnladenSwallow.african,
       UnladenSwallow.european,
       UnladenSwallow.unknown,
       Penguin(name: "King Penguin"),
       SwiftBird(version: 3.0),
       FlappyBird(name: "Felipe", flappyAmplitude: 3.0, flappyFrequency: 20.0),
       Motorcycle(name: "Giacomo")
      ]

    In this code, you first define the protocol Racer and then you make all of the different types conform. Some types, such as Motorcycle conform trivially. Others, such as UnladenSwallow need a bit more logic. In the end, you have a bunch of conforming Racer types.

    With all of the types conforming, you then create an array of racers.

    Top Speed

    Now it’s time to write a function that determines the top speed of the racers. Add this to the end of your playground:

    func topSpeed(of racers: [Racer]) -> Double {
      return racers.max(by: { $0.speed < $1.speed })?.speed ?? 0
    }
     
    topSpeed(of: racers) // 3000

    This function uses the standard library max to find the racer with the largest speed and return that. You return 0 if the user passes in an empty array in for racers.

    Looks like it’s Swift 3 FTW. As if it were ever in doubt! :]

    Making it more generic

    There is a problem though. Suppose you want to find the top speed for a subset (slice) of racers. Adding this to your playground you get an error:

    topSpeed(of: racers[1...3]) // ERROR

    Swift complains it cannot subscript a value of type [Racer] with an index of type CountableClosedRange. Slicing returns one of those wrapper types.

    The solution is to write your code against a common protocol instead of the concrete Array. Add the following before the topSpeed(of:) call.

    func topSpeed<RacerType: Sequence>(of racers: RacerType) -> Double
        where RacerType.Iterator.Element == Racer {
      return racers.max(by: { $0.speed < $1.speed })?.speed ?? 0
    }

    This might look a bit scary, so let’s break it down. RacerType is the generic type for this function and it can be any type that conforms to the Swift standard library’s Sequence protocol. The where clause specifies that the element type of the sequence must conform to your Racer protocol. All Sequence types have an associated type named Iterator that can loop through types of Element. The actual method body is mostly the same as before.

    This method works for any Sequence type including array slices.

    topSpeed(of: racers[1...3]) // 42

    Making it More Swifty

    You can do even a little better. Borrowing from the standard library play book, you can extend Sequence type itself so that topSpeed() is readily discoverable. Add the following to the end of your playground:

    extension Sequence where Iterator.Element == Racer {
      func topSpeed() -> Double {
        return self.max(by: { $0.speed < $1.speed })?.speed ?? 0
      }
    }
     
    racers.topSpeed()        // 3000
    racers[1...3].topSpeed() // 42

    Now you have a method that is easily discoverable but only applies (and autocompletes) when you are dealing with sequences of racers.

    Protocol Comparators

    One Swift 3 improvement to protocols is how you create operator requirements.

    Add the following to the bottom of the playground:

    protocol Score {
      var value: Int { get }
    }
     
    struct RacingScore: Score {
      let value: Int
    }

    Having a Score protocol means that you can write code that treats all scores the same way. However, by having different concrete types such as RacingScore you are sure not to mix up these scores with style scores or cuteness scores. Thanks compiler!

    You really want scores to be comparable so you can tell who has the high score. Before Swift 3, you needed to add global operator functions to conform to these protocols. Now you can define these static method that is part of the model. Do so now by replacing the definition of Score and RacingScore with the following:

    protocol Score: Equatable, Comparable {
      var value: Int { get }
    }
     
    struct RacingScore: Score {
      let value: Int
     
      static func ==(lhs: RacingScore, rhs: RacingScore) -> Bool {
        return lhs.value == rhs.value
      }
     
      static func <(lhs: RacingScore, rhs: RacingScore) -> Bool {
        return lhs.value < rhs.value
      }
    }

    You just encapsulated all of the logic for RacingScore in one place. Now you can compare scores, and, with the magic of protocol extension default implementations, even use operators such as greater-than-or-equal-to that you never explicitly defined.

    RacingScore(value: 150) >= RacingScore(value: 130)  // true

    Where To Go From Here?

    You can download the complete playground with all the code in this tutorial
    here.

    You’ve seen the power of protocol-oriented programming by creating your own simple protocols and extending them using protocol extensions. With default implementations, you can give existing protocols common and automatic behavior, much like a base class but better since it can apply to structs and enums too.

    In addition, protocol extensions can not only be used to extend your own protocols, but can extend and provide default behavior to protocols in the Swift standard library, Cocoa, Cocoa Touch, or any third party library.

    To continue learning more about protocols, you should read the official Apple documentation.

    You can view an excellent WWDC session on Protocol Oriented Programming on Apple’s developer portal for a more in-depth look into the theory behind it all.

    The rationale for operator conformance can be found on the Swift evolution proposal. You might also want to learn more about Swift collection protocols and learn how to build your own.

    Finally, as with any “new” programming paradigm, it is easy to get overly exuberant and use it for all the things. This interesting blog post by Chris Eidhof reminds us that we should beware of silver bullet solutions and using protocols everywhere “just because”.

    Have any questions? Let us know in the forum discussion below!

    The post Introducing Protocol-Oriented Programming in Swift 3 appeared first on Ray Wenderlich.

    Screencast: Server Side Swift with Vapor: Basic Validation

    Screencast: Beginning C# Part 19: Methods

    RWDevCon 2017: Call for Inspiration Speakers

    $
    0
    0

    RWDevCon-feature

    At RWDevCon, most of the time is spent on hands-on tutorials, where you code along with the instructor. This is because we believe the best way to learn a subject is through hands-on experience.

    But we’ve found that after a long day’s work on tutorials, attendees are ready for a break!

    That’s why in the afternoon, we switch gears to inspiration talks. These are 18-minute non-technical talks, designed to fill you with new ideas and energy.

    We are looking for a few select people from the community to join us in this track and share some of their incredible experience and stories.

    If you are a great speaker with a powerful message to share, please contact us with the following info:

    • Please send us 1-2 ideas you have for inspiration talks. Remember – these are short 18-minute non-technical talks with the goal of giving your new idea, some battle-won advice, and leaving you excited and energized. You can watch examples here (search inspiration).
    • Can you arrive on Wed March 29, 2017, and depart Sun April 2, 2017?
    • Please send us links to any videos you have of you giving a talk.
    • Please send us a brief history of your background and major accomplishments.

    Inspiration speakers get a free ticket, 4-nights at the conference hotel, and reimbursement for their flight.

    Please send your application by next Friday, Dec 16. Please understand that although we wish we could invite everyone kind enough to volunteer for this, slots are limited.

    We can’t wait to hear from you! :]

    The post RWDevCon 2017: Call for Inspiration Speakers appeared first on Ray Wenderlich.

    Viewing all 4373 articles
    Browse latest View live


    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>