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

UIScrollView Tutorial: Getting Started

$
0
0
uiscrollview tutorial

Learn how to use UIScrollViews for paging, zooming, scrolling, and more!

Note from Ray: This is a Swift update to a popular Objective-C tutorial on our site. Update to Swift, iOS 9 and Xcode 7.1.1 by Corinne Krych; Original post by Tutorial Team member Matt Galloway. Enjoy!

UIScrollView is one of the most versatile and useful controls in iOS. It is the basis for the very popular UITableView and is a great way to present content larger than a single screen. In this UIScrollView tutorial, by building an app very similar to the Photos app, you’ll learn all about using this control. You’ll learn:

  • How to use a UIScrollView to zoom and view a very large image.
  • How to keep the UIScrollView‘s content centered while zooming.
  • How to use UIScrollView for vertical scrolling with Auto Layout.
  • How to keep text input components visible when the keyboard is displayed.
  • How to use UIPageViewController, in conjunction with UIPageControl, to allow scrolling through multiple pages of content.

This tutorial assumes that you know how to use Interface Builder to add new objects to a view and connect outlets between your code and the Storyboard. You’ll want to be familiar with Storyboards before proceeding, so definitely take a look at our Storyboards tutorial if you’re new to them.

Getting Started

Click here to download the starter project for this UIScrollView tutorial, and then open it in Xcode.

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

uiscrollview tutorial

When selecting a photo, you can see it full sized. But, sadly, the photo is cropped. You can not see the whole image with the limited size of your device. What you really want is for the image to fit the device’s screen by default, and then be able to zoom to see details as you would do in the Photos app.

Can you fix it? Yes you can!

Scrolling and Zooming a Large Image

The first thing you’re going to learn in this UIScrollView tutorial is how to set up a scroll view that allows the user to zoom into an image and pan around.

First, you need to add a Scroll View. Open Main.storyboard, drag a Scroll View from the Object Library and drop it in Document Outline just under View of Zoomed Photo View Controller Scene. Move Image View inside your newly added Scroll View. Your document outline should now look like this:

uiscrollview tutorial

See that red dot? Xcode is now complaining that your Auto Layout rules are not properly defined. To fix them first select your Scroll View. Tap the Pin button at the bottom of the storyboard window. Add four new constraints: top, bottom, leading and trailing spaces. Uncheck Constrain to margins and set all the constraint constants to 0.

uiscrollview tutorial

Now select Image View and add the same four constraints to that view.

Resolve the Auto Layout warning by selecting Zoomed Photo View Controller in Document Outline, and then selecting Editor\Resolve Auto Layout Issues\Update Frames.

Finally, uncheck Adjust Scroll View Insets in Attributes Inspector for Zoomed Photo View Controller.

Build and run.

uiscrollview tutorial

Thanks to the Scroll View you can now see the full size image by swiping. But what if you want to see the picture scaled to fit the device screen? Or what if you want to zoom in or out of the photo?

Ready to start with some coding?

Open ZoomedPhotoViewController.swift, inside the class declaration, add the following outlet properties:

@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var imageViewBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var imageViewLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var imageViewTopConstraint: NSLayoutConstraint!
@IBOutlet weak var imageViewTrailingConstraint: NSLayoutConstraint!

Back in Main.storyboard, wire up the Scroll View to the Zoomed View Controller by attaching it to the scrollView outlet and setting Zoomed View Controller as the Scroll View’s delegate. Also, connect the new constraint outlets from Zoomed View Controller to the appropriate constraints in the Document Outline like this:

uiscrollview tutorial

Now you’re going to get down and dirty with the code. In ZoomedPhotoViewController.swift, add the implementation of the UIScrollViewDelegate‘s methods as an extension:

extension ZoomedPhotoViewController: UIScrollViewDelegate {
  func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
    return imageView
  }
}

This is the heart and soul of the scroll view’s zooming mechanism. You’re telling it which view should be made bigger and smaller when the scroll view is pinched. So, you tell it that it’s your imageView.

Now, add the implementation of updateMinZoomScaleForSize(_:) to the ZoomedPhotoViewController class:

private func updateMinZoomScaleForSize(size: CGSize) {
  let widthScale = size.width / imageView.bounds.width
  let heightScale = size.height / imageView.bounds.height
  let minScale = min(widthScale, heightScale)
 
  scrollView.minimumZoomScale = minScale
 
  scrollView.zoomScale = minScale
}

You need to work out the minimum zoom scale for the scroll view. A zoom scale of one means that the content is displayed at normal size. A zoom scale below one shows the content zoomed out, while a zoom scale of greater than one shows the content zoomed in. To get the minimum zoom scale, you calculate how far you’d need to zoom out so that the image fits snugly in your scroll view’s bounds based on its width. Then you do the same based upon the image’s height. The minimum of those two resulting zoom scales will be the scroll view’s minimum zoom scale. That gives you a zoom scale where you can see the entire image when fully zoomed out. Note that maximum zoom scale defaults to 1. You leave it as the default because zooming in more than what the image’s resolution can support will cause it to look blurry.

You set the initial zoom scale to be the minimum, so that the image starts fully zoomed out.

Finally, update the minimum zoom scale each time the controller updates it’s subviews:

override func viewDidLayoutSubviews() {
  super.viewDidLayoutSubviews()
 
  updateMinZoomScaleForSize(view.bounds.size)
}

Build and run. You should get the following result:

uiscrollview tutorial

You can zoom and the image is displayed in portrait mode to fill the whole screen. But there are several glitches:

  • The image is pinned at the top of view. It would be nice to have it centered.
  • If you turn you phone to landscape orientation, your view doesn’t get resized.

Still in ZoomedPhotoViewController.swift implement the updateConstraintsForSize(size:) function to fix these issues:

private func updateConstraintsForSize(size: CGSize) {
 
  let yOffset = max(0, (size.height - imageView.frame.height) / 2)
  imageViewTopConstraint.constant = yOffset
  imageViewBottomConstraint.constant = yOffset
 
  let xOffset = max(0, (size.width - imageView.frame.width) / 2)
  imageViewLeadingConstraint.constant = xOffset
  imageViewTrailingConstraint.constant = xOffset
 
  view.layoutIfNeeded()
}

The method helps to get around a slight annoyance with UIScrollView: if the scroll view content size is smaller than its bounds, then it sits at the top-left rather than in the center. Since you’ll be allowing the user to zoom all the way out, it would be nice if the image sat in the center of the view. This function accomplishes that by adjusting the layout constraints.

You center the image vertically by subtracting the height of imageView from the view‘s height and dividing it in half. This value is used as padding for the top and bottom imageView constraints.

Likewise, you calculate an offset for the leading and trailing constraints of imageView.

In the UIScrollViewDelegate extension, add scrollViewDidZoom(_:) implementation:

func scrollViewDidZoom(scrollView: UIScrollView) {
  updateConstraintsForSize(view.bounds.size)
}

Here, the scroll view re-centers the view each time the user scrolls – if you don’t, the scroll view won’t appear to zoom naturally; instead, it will sort of stick to the top-left.

Now take a deep breath, give yourself a pat on the back and build and run your project! Tap on an image and if everything went smoothly, you’ll end up with a lovely image that you can zoom, pan and tap. :]

uiscrollview tutorial

Scrolling Vertically

Now suppose you want to change PhotoScroll to display the image at the top and add comments below it. Depending on how long the comment is, you may end up with more text than your device can display: Scroll View to the rescue!

Note: In general, Auto Layout considers the top, left, bottom, and right edges of a view to be the visible edges. However, UIScrollView scrolls its content by changing the origin of it’s bounds. To make this work with Auto Layout, the edges within a scroll view actually refer to the edges of its content view.

To size the scroll view’s frame with Auto Layout, constraints must either be explicit regarding the width and height of the scroll view, or the edges of the scroll view must be tied to views outside of its own subtree.

You can read more in this technical note from Apple.

You’ll see, in practice, how to fix the width of a scroll view, or really its content size width, using auto layout in storyboards.

Scroll view and Auto Layout

Open Main.storyboard and lay out a new scene:

First, add a new View Controller. In Size Inspector, for the Simulated Size, replace Fixed with Freeform and enter a width of 340 and a height of 800. You’ll notice the layout of the controller gets narrower and longer, simulating the behavior of a long vertical content. The simulated size helps you visualize the display in Interface Builder. It has no runtime effect.

Uncheck Adjust Scroll View Insets in the Attributes Inspector for your newly created view controller.

Add a Scroll View that fills the entire space of the view controller. Add leading and trailing constraints with constant values of 0 to the view controller. (Make sure to uncheck Constrain to margin). Add top and bottom constraints from Scroll View to the Top and Bottom Layout guides, respectively. They should also have constants of 0.

Add a View as a child of the Scroll View that takes the entire space of the Scroll View. Rename its storyboard Label to Container View. Like before, add top, bottom, leading and trailing constraints.

To define the size of the scroll view and fix the Auto Layout errors, you need to define its content size. Define the width of Container View to match the view controller’s width. Attach an equal width constraint from the Container View to the View Controller’s main view. For the height of Container View define a height constraint of 500.

Note: Auto Layout rules must comprehensively define a Scroll View’s contentSize. This is the key step in getting a Scroll View to be correctly sized when using Auto Layout.

Add an Image View inside Container View. In Attributes Inspector: specify photo1 as the image, choose Aspect Fit mode and check Clip Subviews. Add top, leading, and trailing constraints to Container View like before. Add n width constraint of 300 to the image view.

Add a Label inside of Container View below the image view. Specify the label’s text as: What name fits me best? Add a centered horizontal constraint to Container View. Add a vertical spacing constraint of 0 with Photo View.

Add a Text Field inside of Container View, right below the new label. Add leading and trailing constraints to Container View with constant values of 8, and no margin. Add a vertical spacing constraint of 30 with the label.

Finally, connect your newly created View Controller to another screen via a segue. Remove the existing push segue between the Photo Scroll scene and the Zoomed Photo View Controller scene. Don’t worry, all the work you’ve done on Zoomed Photo View Controller will be added back to your app later.

In the Photo Scroll scene, from PhotoCell, control-drag to View Controller, add a show segue. Make the identifier showPhotoPage.

Build and Run.

uiscrollview tutorial

You can see that layout is correct in vertical orientation. Try rotating to landscape orientation. In landscape, there is not enough vertical room to show all the content, yet the scroll view allows you to properly scroll to see the label and the text field. Unfortunately, since the image in the new view controller is hard-coded, the image you selected in the collection view is not shown.

To fix this, you’ll need to pass it along to the view controller when the segue is executed. So, create a new file with the iOS\Source\Cocoa Touch Class template. Name the class PhotoCommentViewController and set the subclass to UIViewController. Make sure that the language is set to Swift. Click Next and save it with the rest of the project.

Update PhotoCommentViewController.swift with this code:

import UIKit
 
public class PhotoCommentViewController: UIViewController {
  @IBOutlet weak var imageView: UIImageView!
  @IBOutlet weak var scrollView: UIScrollView!
  @IBOutlet weak var nameTextField: UITextField!
  public var photoName: String!
 
  override public func viewDidLoad() {
    super.viewDidLoad()
    if let photoName = photoName {
      self.imageView.image = UIImage(named: photoName)
    }
  }
}

This updated implementation of PhotoCommentViewController adds IBOutlets, and sets the image of imageView based on a photoName.

Back in the storyboard, open the Identity Inspector for View Controller, select PhotoCommentViewController for the Class. Open the Connections Inspector and wire up the IBOutlets for the Scroll View, Image View and Text Field of PhotoCommentViewController.

Open CollectionViewController.swift, replace prepareForSegue(_:sender:) with:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
  if let cell = sender as? UICollectionViewCell,
      indexPath = collectionView?.indexPathForCell(cell),
      photoCommentViewController = segue.destinationViewController as? PhotoCommentViewController {
    photoCommentViewController.photoName = "photo\(indexPath.row + 1)"
  }
}

This sets the name of the photo to be shown on PhotoCommentViewController when one of the photos is tapped.

Build and run.

uiscrollview tutorial

Your view nicely displays the content and when needed allows you to scroll down to see more. You’ll notice two issues with the keyboard: first, when entering text, the keyboard hides the Text Field. Second, there is no way to dismiss the keyboard. Ready to fix the glitches?

Keyboard

Keyboard offset

Unlike when using UITableViewController where it manages moving content out of the way of the on-screen keyboard, when working with UIScrollView you have to deal with handling the keyboard appearance by yourself.

View controllers can make adjustments to their contents when the keyboard appears by listening for NSNotifications issued by iOS. The notifications contain a dictionary of geometry and animation parameters that can be used to smoothly animate the contents out of the way of the keyboard. You’ll first update your code to listen for those notifications. Open PhotoCommmentViewController.swift, and add the following code at the bottom of viewDidLoad():

NSNotificationCenter.defaultCenter().addObserver(
  self,
  selector: "keyboardWillShow:",
  name: UIKeyboardWillShowNotification,
  object: nil
)
 
NSNotificationCenter.defaultCenter().addObserver(
  self,
  selector: "keyboardWillHide:",
  name: UIKeyboardWillHideNotification,
  object: nil
)

When the view loads, you will begin listening for notifications that the keyboard is appearing and disappearing.

Next, add the following code, to stop listening for notifications when the object’s life ends:

deinit {
  NSNotificationCenter.defaultCenter().removeObserver(self)
}

Next add the following methods to the view controller:

func adjustInsetForKeyboardShow(show: Bool, notification: NSNotification) {
  let userInfo = notification.userInfo ?? [:]
  let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()
  let adjustmentHeight = (CGRectGetHeight(keyboardFrame) + 20) * (show ? 1 : -1)
  scrollView.contentInset.bottom += adjustmentHeight
  scrollView.scrollIndicatorInsets.bottom += adjustmentHeight
}
 
func keyboardWillShow(notification: NSNotification) {
  adjustInsetForKeyboardShow(true, notification: notification)
}
 
func keyboardWillHide(notification: NSNotification) {
  adjustInsetForKeyboardShow(false, notification: notification)
}

adjustInsetForKeyboardShow(_:,notification:) takes the keyboard’s height as delivered in the notification, adds a padding value of 20 to either be subtracted from or added to the scroll views’s contentInset. This way, the UIScrollView will scroll up or down to let the UITextField always be visible on the screen.

When the notification is fired, either keyboardWillShow(_:) or keyboardWillHide(_:) will be called. These methods will then call adjustInsetForKeyboardShow(_:,notification:), indicating which direction to move the scroll view.

Dismissing the Keyboard

To dismiss the keyboard, add this method to PhotoCommentViewController.swift:

@IBAction func hideKeyboard(sender: AnyObject) {
  nameTextField.endEditing(true)
}

This method will resign the first responder status of the text field which will, in turn, close the keyboard.

Finally, open Main.storyboard. From Object Library drag a Tap Gesture Recognizer into the root view. Then, wire it to the hideKeyboard(_:) IBAction in Photo Comment View Controller.

Build and run.

uiscrollview tutorial

Tap the text field, and then tap somewhere else on the screen. The keyboard should properly show and hide itself relative to the other content on the screen.

Paging with UIPageViewController

In the third section of this UIScrollView tutorial, you’ll be creating a scroll view that allows paging. This means that the scroll view locks onto a page when you stop dragging. You’ll see this in action in the App Store app when you view screenshots of an app.

Add UIPageViewController

Go to Main.storyboard, drag a Page View Controller from the Object Library. Open Identity Inspector, enter PageViewController for the Storyboard ID. In Attributes Inspector, the Transition Style is set to Page Curl by default; change it to Scroll and set the Page Spacing to 8.

In the Photo Comment View Controller scene’s Identity Inspector, specify a Storyboard ID of PhotoCommentViewController, so that you can refer to it from code.

Open PhotoCommentViewController.swift and add:

public var photoIndex: Int!

This will reference the index of the photo to show and will be used by the page view controller.

Create a new file with the iOS\Source\Cocoa Touch Class template. Name the class ManagePageViewController and set the subclass to UIPageViewController . Make sure that the language is set to Swift. Click Next and save it with the rest of the project.

Open ManagePageViewController.swift and replace the contents of the file with the following:

import UIKit
 
class ManagePageViewController: UIPageViewController {
  var photos = ["photo1", "photo2", "photo3", "photo4", "photo5"]
  var currentIndex: Int!
 
  override func viewDidLoad() {
    super.viewDidLoad()
 
    dataSource = self
 
    // 1
    if let viewController = viewPhotoCommentController(currentIndex ?? 0) {
      let viewControllers = [viewController]
      // 2
      setViewControllers(
        viewControllers,
        direction: .Forward,
        animated: false,
        completion: nil
      )
    }
  }
 
  func viewPhotoCommentController(index: Int) -> PhotoCommentViewController? {
    if let storyboard = storyboard,
        page = storyboard.instantiateViewControllerWithIdentifier("PhotoCommentViewController")
        as? PhotoCommentViewController {
      page.photoName = photos[index]
      page.photoIndex = index
      return page
    }
    return nil
  }
}

Here’s what this code does:

  1. viewPhotoCommentController(_:_) creates an instance of PhotoCommentViewController though the Storyboard. You pass the name of the image as a parameter so that the view displayed matches the image you selected in previous screen.
  2. You setup the UIPageViewController by passing it an array that contains the single view controller you just created.

You’ll notice that you have an Xcode error indicating that delegate cannot be assigned a value of self. This is because ManagePageViewController does not yet conform to UIPageViewControllerDataSource. Add the following in ManagePageViewController.swift but outside of the ManagePageViewController definition:

//MARK: implementation of UIPageViewControllerDataSource
extension ManagePageViewController: UIPageViewControllerDataSource {
  // 1
  func pageViewController(pageViewController: UIPageViewController,
      viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
 
    if let viewController = viewController as? PhotoCommentViewController {
      var index = viewController.photoIndex
      guard index != NSNotFound && index != 0 else { return nil }
      index = index - 1
      return viewPhotoCommentController(index)
    }
    return nil
  }
 
  // 2
  func pageViewController(pageViewController: UIPageViewController,
      viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
 
    if let viewController = viewController as? PhotoCommentViewController {
      var index = viewController.photoIndex
      guard index != NSNotFound else { return nil }
      index = index + 1
      guard index != photos.count else {return nil}
      return viewPhotoCommentController(index)
    }
    return nil
  }
}

The UIPageViewControllerDataSource allows for you to provide content when the page changes. You provide view controller instances for paging in both the forward and backward directions. In both cases, photoIndex is used to determine which image is currently being displayed. (The viewController parameter to both methods indicates the currently displayed view controller.) Based on the photoIndex a new controller is created and returned for either method.

There are only a couple things left to do to get your page view running. First, you will fix the application flow of the app. Switch back to Main.storyboard and select your newly created
Page View Controller scene. Then, in the Identity Inspector, specify ManagePageViewController for its class. Delete the push segue showPhotoPage you created earlier. Control drag from Photo Cell in Scroll View Controller to Manage Page View Controller Scene and select a Show segue. In the Attributes Inspector for the segue, specify its name as showPhotoPage.

Open CollectionViewController.swift and change the implementation of prepareForSegue(_:sender:) to the following:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
  if let cell = sender as? UICollectionViewCell,
      indexPath = collectionView?.indexPathForCell(cell),
      managePageViewController = segue.destinationViewController as? ManagePageViewController {
    managePageViewController.photos = photos
    managePageViewController.currentIndex = indexPath.row
  }
}

Build and run.

uiscrollview tutorial

You can now scroll side to side to page between different detail views. :]

Display Page Control indicator

For the final part of this UIScrollView tutorial, you will add a UIPageControl to your application.

UIPageViewController has the ability to automatically provide a UIPageControl. To do so, your UIPageViewController must have a transition style of UIPageViewControllerTransitionStyleScroll, and you must provide implementations of two special methods of UIPageViewControllerDataSource. (If you remember, you already set the Transition Style to Scroll in the Storyboard). Add these methods to the UIPageViewControllerDataSource extension in ManagePageViewController.swift:

// MARK: UIPageControl
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
  return photos.count
}
 
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
  return currentIndex ?? 0
}

In the first method, you specify the number of pages to display in the page view controller. And, in the second method, you tell page view controller which page should initially be selected.

After you’ve implemented the required delegate methods, you can add further customization with the UIAppearance API. In AppDelegate.swift, replace application(application: didFinishLaunchingWithOptions:) with:

func application(application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
 
  let pageControl = UIPageControl.appearance()
  pageControl.pageIndicatorTintColor = UIColor.lightGrayColor()
  pageControl.currentPageIndicatorTintColor = UIColor.redColor()
  return true
}

This will customize the colors of the UIPageControl.

Build and run.

uiscrollview tutorial

Putting it all together

Almost there! The very last step is to add back the zooming view when tapping an image. Open PhotoCommentViewController.swift and add the following:

@IBAction func openZoomingController(sender: AnyObject) {
  self.performSegueWithIdentifier("zooming", sender: nil)
}
 
override public func prepareForSegue(segue: UIStoryboardSegue,
    sender: AnyObject?) {
  if let id = segue.identifier,
      zoomedPhotoViewController = segue.destinationViewController as? ZoomedPhotoViewController {
    if id == "zooming" {
      zoomedPhotoViewController.photoName = photoName
    }
  }
}

In Main.storyboard, add a Show Detail segue from Photo Comment View Controller to Zoomed Photo View Controller. With the new segue selected, open the Identity Inspector, set the Identifier to zooming.

Select the Image View in Photo Comment View Controller, open the Attributes Inspector and check User Interaction Enabled. Add a Tap Gesture Recognizer, and connect it to openZoomingController(_:).

Now, when you tap an image in Photo Comment View Controller Scene, you’ll be taken to the Zoomed Photo View Controller Scene where you can zoom the photo.

Build and run one more time.

uiscrollview tutorial

Yes you did it! You’ve created a Photos app clone: a collection view of images you can select and navigate through by swiping, as well as the ability to zoom the photo content.

Where to Go From Here?

Here is the final PhotoScroll project with all of the code from this UIScrollView tutorial.

You’ve delved into many of the interesting things that a scroll view is capable of. If you want to go further, there is an entire 21-part video series dedicated to scroll views. Take a look.

Now go make some awesome apps, safe in the knowledge that you’ve got mad scroll view skills!

If you run into any problems along the way or want to leave feedback about what you’ve read here, join in the discussion in the comments below.

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


Video Tutorial: Beginning watchOS Part 5: Context Menus & Actions

Video Tutorial: Beginning watchOS Part 6: Navigation & Contexts

Video Tutorial: Beginning watchOS Part 7: Modals & Pages

RWDevCon 2016 Post-Mortem

$
0
0

Thumb2

We recently finished our second annual hands-on tutorial conference: RWDevCon 2016.

This year the conference was a little bit bigger than last year. Last year was 180 attendees – this year 270. We have people from 17 countries across the world – countries like El Salvador, Poland, Indonesia, Argentina, and more – it was great to see such a nice diversity of people.

The conference was a huge hit! We received an overwhelmingly positive response on our evaluation forms, with a whopping 4.64 / 5 overall rating.

I thought you might like to see to see some pictures and feedback from the attendees, so that’s what this post is all about.

Then we’ll get into the post-mortem, with three things that went well, and three things that we can improve upon in the future. Let’s dive in!

Conference Highlights

At some conferences, you fly in the night before and feel like hanging out, but it’s hard to get a group together. To fix that, at RWDevCon we started with an optional opening reception!

ReceptionMixed

Passed appetizers, beer, and mojitos – oh my :]

The next morning, we started bright and early with an opening keynote. I discussed some of my struggles with motivation, in a speech titled “Feed Your Fire”:

FeedYourFire2

We then started moving into hands-on programming tutorials – the meat of the conference. Instead of just watching the instructor, attendees live coded along with the instructor.

HandsOn

Some of our most popular sessions were Advanced LLDB debugging, App Architecture, Protocol-Oriented Programming, and more.

After a bunch of tutorials, we switched over to what we call “inspiration talks”. These are short 18-minute talks designed to give you a new idea, share some battle-won advice, or challenge you to try something new.

Inspiration

After the day was over, we headed over to a conference party at the swanky Carlyle club across the street. We had great food, drinks, and an awesome and hilarious performance by James Dempsey and the Breakpoints:

JamesFinal

After that, we had one more day chock full of tutorials and inspiration talks. Once it was all over, we wrapped things up with a special surprise: everyone at the conference got a free pre-release copy of our upcoming new book, 3D iOS Games by Tutorials!

SideView

Note: If you weren’t at the conference, this book will be released on our site soon – stay tuned! :]

As people walked out the door, everyone got passed a glass of champagne and was welcomed to a surprise closing reception with sushi, quesadillas, and brie. It was awesome to have one last chance to toast all our hard work and to say goodbye.

ClosingReception

What Went Well

A conference like this takes a lot of work, and often makes me wonder “is this really worth it?”

But this year got such a positive response from people who came, that I can answer with a resounding yes. Here are a few comments from our conference evaluation forms this year:

“This was my first iOS dev conference. I don’t think I could have made a better decision. Thank you RW team and your amazing coordination and supplying an amazing networking and learning experience.”

“There is simply no better way to get up to speed and learn new things than this conf. Better than WWDC!”

“Great topics, great lectures, friendly people and staff. I appreciate all the hard work the RW team put forth.”

Here are three things I think went particularly well about the conference.

1) Hands-On Tutorials

Just like last year, the hands-on focus of the conference was a huge hit, and definitely something that sets us apart from other conferences. If you want to attend a conference primarily to learn new skills, this is the conference for you.

25409317000_041399b123_k

We tweaked the format a bit this year to give more time for tutorials, and we made a push to make the advanced track more advanced, and I was happy to see that people really felt like they were learning new things and having fun.

“Brilliant tutorials. Code to take with me and use. Best practice examples, and good spirit.”

“Expert speakers. Very much challenged me to dig deeper! Speakers are definitely professionals in their fields.”

“The hands-on nature makes this a great mix of conference and training. Will certainly return each year!”

2) Team Coordination

This conference takes a huge amount of prep work. Each speaker gets their outline and sample projects reviewed by a tech editor, then goes through a round of practice with their tech editor, and then a final round of practice with me.

But the end result shows – we end up with a suite of coordinated tutorials that are to the high quality standards our site is known for.

TeamCoord

In fact, since we were prepared so far in advance, we were even able to put together all of our demo instructions and labs into a 600 page conference book, which we gave for free to all attendees!

ConferenceBook

I bet you’ve never seen that at a conference before :]

“Loved the conference book – awesome!”

“Everything was so well organized and executed. I learned so much!”

“Awesome coordination and run so professionally. Excellent material and speakers. Thank you!”

3) Friendship

We try our best to make RWDevCon a friendly and open environment where you can meet new people and make friends.

In addition to the massive amount of conference parties, one thing we do each year to encourage socializing is play board games at the conference. At lunch, we set aside a certain are as a “board game zone” where people could sit down and play games together:

BoardGamesFinal

This is a great way for introverts like me to meet new people and have fun in a low-risk environment :]

“Very inclusive feeling environment.”

“Everybody was nice and the community made it great.”

“This is the best conference to meet other people!”

What Could Be Improved

As with anything, there are always some things you can improve. Here are the top 3 in my opinion.

1) Pacing

It’s difficult to get the right pacing in a hands-on tutorial. You don’t want to go too fast, or you might end up leaving audience members behind, and you don’t want to go too slow, or you’ll bore people.

RWDevCon20160209_4186

Pacing is something that sometimes we got right, but sometimes we could have improved upon. Next year, we’re hoping to improve our speaker training in this area.

2) Technical Issues

This year we did a major upgrade of our A/V systems at the conference, including music between sessions, rear projection, recordings of all sessions, and more.

Tech

Along with this added complexity came some technical difficulties. We’ve learned from these and aim to smooth them out in the years to come :]

3) More Days

For me, this second year of RWDevCon was all about iteration. I wanted to take the format that worked so well last year, and tweak and polish it.

RyanNystrom

Now that we have a solid format, I think it would be great if we could expand to a 3 day conference. This would give a bit more time to spread things out and try some different things that wouldn’t have fit in a 2 day conference. I am excited about what we can do next year!

Where To Go From Here?

For everyone asking – yes, we are planning on having a RWDevCon 2017 next year!

The conference has sold out for two years in a row now, so you won’t want to miss your chance at getting a ticket.

We will email everyone who is on our conference newsletter first before we announce the event publicly. If you’d like to be notified if/when tickets become available, sign up here!

Thanks again for everyone who helped make the first ever RWDevCon a success – speakers, attendees, sponsors, and more!

Photo Credits: Fuad Kamal, Greg Heo, Kelvin Lau, Michael McDonald. Thanks all!

The post RWDevCon 2016 Post-Mortem appeared first on Ray Wenderlich.

Best Image Editors for OS X

$
0
0

Best-image-editors-feature

As an app developer, it isn’t long before you have a need for some type of image editor. But searching for image editor in the Mac App Store returns more than 400 results!

This makes it extremely difficult to find the right tool for your needs. Raster or vector? And what file formats does each tool support? You’re a busy developer and you don’t have time to review them all.

To that end, we’ve compiled a list of the five best image editors for OS X, based on the tools most used (and most loved) by the raywenderlich.com team. We asked people what they liked about their favorite image editor, what they didn’t like, and why they chose this tool over others.

As a bonus, we’ll give you a quick tour of each tool as we create a simple image. If you’d like, you could follow along with this to see the workflow for each tool, which may help you pick your personal favorite.

Ready to push some pixels? Time to get started!

Getting Started

Start by downloading the starter files for this tutorial, and unzip the file.

As mentioned, for each tool we cover in this article, we’ll show you how to create a simple image. Specifically, you’ll start with the following background image:

Background Image

…add an overlay image:

Overlay Image

…and finally add the text Such Tutorials Much Wow in Open Sans 26pt with a white outer stroke to create the following image:

Sample Image

This image could be used to promote a blog post on this site. The process of creating it shows some typical operations developers need to perform – resizing images, combining images, adding text, and so on.

Without further ado, let’s get into our picks for the top 5 OS X image editors!

5. Affinity Designer

Price: $49.99
Pros: A powerful design app at a good price; has better bitmap editing abilities than most vector-based tools; good replacement for Adobe Illustrator.
Cons: Built for designers, not developers.

Getting Affinity Designer

You can download Affinity Designer frpm the Mac App Store. You can request a ten-day trial by entering your contact information on the Affinity web site; they’ll email you a download link to the trial DMG.

To install the trial, open the DMG and drag the Affinity Designer Trial.app file onto the Applications shortcut in the window.

Building the Image in Affinity Designer

Run Affinity Designer, select File\Open… and choose Twitter_card_overlay.png:

Step 1

Now to load your background image. Select the Place Image Tool from your Tools panel and choose the Twitter_card_bg_image.png file. Click near the center of the overlay image to add the background image as a new layer above the overlay image:

Step 2

The background image appears in front of the overlay. Fix this by dragging the layer with the overlay above the background layer:

affinity_tut_3

Make sure to drag it above the background layer and not onto the background layer, or you’ll create a layer mask instead of moving the layer to the front.

You can use Transform options to resize the background layer to the same width as the overlay layer.

Select the Twitter_card_bg_image layer, then click on the small link icon next to the length and width settings to lock the aspect ratio:

Step 4

This tells Affinity Designer that changing the width of the image should change the height of the image in a proportional manner — or vice versa.

Change the width of the card layer to 640 to match the size of the overlay layer; the height will automatically change to 400.

Now to center the background. In the small grid of squares to the left of the X and Y settings, select the middle square; this tells Affinity Designer position values you enter will be relative to the center of the overall image. As the overlay is 640 x 320 pixels wide, set X to 320 and Y to 160 to center within the image.

Your image should now look like the following:

Step 4b

To add text to the image, click on the Text Tool. Change the font to Open Sans and enter 26 for the font size. Click on the image near the bottom left of the overlay and enter Such Tutorials Much Wow:

Step 5

If the text isn’t exactly where you wanted it, use the Move Tool to adjust the position of the text layer.

You can add the white outer stroke as an effect on the text layer. Select the text layer and click the Effects tab next to the Layer tab. Scroll through the list of effects and check Outline which displays several options:

Step 6

Click the box next to Colour; leave the opacity at 100% and change the radius to 3 px. Your final image should look like the screenshot below:

Final Affinity Designer Image

Why Use Affinity Designer?

DesignAward

Serif’s Affinity Designer is a full-featured, vector-based graphic design software that works well in the OS X environment and takes advantage of key OS X features. In fact, it does this so well that it received an Apple Design Award at the June 2015 WWDC!

Although it’s a vector-based tool, Affinity Designer also provides a solid set of tools to work with raster images. Its bitmap editing abilities don’t match a dedicated tool like Pixelmator or Adobe Photoshop, but they’re still a notch above most editing apps.

Affinity Designer is true tool for graphics designers; while it can create the graphics for your next app, you could easily use to design anything from your business card up to to a full-color marketing brochure for your company. If you’re experienced with Illustrator, you’ll adjust quickly adjust to this app.

While Affinity Designer is primarily for graphics designers, features such as the ability to automatically export standard and retina versions of images in a single step are a great benefit to app developers as well.

Affinity Designer is half the price of Sketch, and I think it handles some things better than Sketch, such as working with 3D elements. While Affinity Designer is a powerful tool, it’s probably not going to be your first choice — unless you’re a designer and a developer who spends a lot of time in tools such as Adobe Illustrator.

For developers that don’t have a great need for a design tool, there might be a few better (read: simpler) choices in this list.

4. PaintCode

Price: $99.99
Pros: Can generate Core Graphics code to generate your graphic resources dynamically; good for generating the numerous sizes and resolutions of icons and code to draw custom controls.
Cons: Not a full featured drawing tool.

Getting PaintCode

You can buy PaintCode from the Mac App Store, or you can purchase the app from the PaintCode website. To download a trial version, enter your email address on the site and you’ll receive an email with a link to download the trial version.

Building the Image in PaintCode

Make a stopwatch in PaintCode!

PaintCode is not like the other tools on this list. Generally you wouldn’t use PaintCode to make rasterized images like the example we’ve been working with in this tutorial, so it doesn’t really make sense to run through that example here.

Instead, you would use PaintCode to develop vector graphics that you want to be able to dynamically resize, move, color, or modify in your apps. It’s great for making app icons, custom controls, or anywhere you need Core Graphics code in your apps.

For a better example of when you might want to use PaintCode in your apps, check out these tutorials:

Why Use PaintCode?

PaintCode is the most specialized tool on this list. It does come with good vector image editing ability, but it’s not the best tool for creating or manipulating graphics. It’s best for working with bitmap graphics created in other tools, but it still has two important features for developers: the ability to create icons and generate code for drawing graphics in your app.

While the features of the vector drawing tools are limited compared to other tools on this list, they do work to build app icons. In PaintCode, you build a high-resolution version of the icon on a single canvas, then use that canvas as a symbol for other canvases to match the icon sizes you need for your app.

PaintCode includes built-in templates for several common icon sizes; changes made to the original icon will automatically update the other icon canvases.You can then export all the various sizes and resolutions of the icon for your app in one step; my PaintCode review from November describes this in more detail.

Icon generation is a nice additional feature, but I use PaintCode primarily for code generation. I can take a control that I’ve either built myself or received from a designer, bring it into PaintCode and generate the CoreGraphics code to replicate the image.

Support for variables and simple calculations let you build complex controls with automatic code generation for use in your apps. As mentioned earlier, check out the tutorials PaintCode for Designers and PaintCode for Developers for more information.

Developers building custom controls with Core Graphics or building dynamic graphics will find a lot of value in this tool. If you’re looking for a raster-based tool, or have no need of custom controls, other tools might better fit your needs.

3. Pixelmator

Price: $29.99
Pros: Good raster image editor; cheaper and easier to learn than Photoshop.
Cons: Less powerful than Photoshop; workflow is different than Photoshop; fewer third-party add-ons than Photoshop.

Getting Pixelmator

Pixelmator is available from the Mac App Store; you can also download a 30-day trial from the company’s site without providing contact information. Once you download the trial, unzip the downloaded file and drag the Pixelmator.app file to your Applications folder to install it.

Building the Image in Pixelmator

From the welcome window, click Open existing image…. You can also select File\Open from the menu and choose the Twitter_card_overlay.png image to load it:

Step 1

Select File\Open… again and open the Twitter_card_bg_image.png background image.

To resize this image to match your overlay, select Image\Image Size… to bring up the Image Size dialog. Note the Fit Into dropdown has several convenient sizes such as iPhone, iPad, and iPad Air desktop, but keep the default of Custom in this case.

Pixelmator maintains the aspect ratio by default when you change the image’s size. Set the width to 640 to match the width of our overlay image, and the height will automatically change to 400. Click OK to resize the image:

Step 2

Select Edit\Copy or press Command-C to copy the resized image to the clipboard. Change back to the window with the overlay and paste the image with Edit\Paste or by pressing Command-V. This places the background image on top of the overlay. To fix this, drag the layer containing the overlay above the layer containing the background image:

Step 3

To add text in Pixelmator, select the Type Tool. Use the text settings toolbar at the top of the window to set the text attributes: change the dropdown for the font to Open Sans, and set the font size to 26. By default, Pixelmator centers text within the rectangle. You’d like it to left-align instead, so click the left align button.

Drag out a text area at the bottom of the overlay; clear the default text and enter Such Tutorials Much Wow:

Step 4

Now for the white outer stroke. Right-click on the text layer in the Layers window, then select Show Styles to bring up the Styles window for this layer.

Change the Stroke setting from None to Color, then click the color icon and change the color from black to white by dragging the brightness slider all the way to the left. You can close the color window at this point.

To change the width of the stroke, drag the slider or type the value 3 in the field. Change the Style to Outside, since you want an outer stroke, not an inner stroke:

Step 5

You can close the Styles window at this point. The layers window now shows a small fx next to the text layer; this indicates the text carries a style effect.

Step 5

Your final image should look like the following:

Pixelmator Final Image

Why Use Pixelmator?

Pixelmator does what you’d expect of a raster image editor, and does it well. It comes with support for resizing, cropping, painting, retouching, color correction and transforms. It also supports more advanced editing with layers, masks, and photo effects including blurring, sharpening and distortion. Pixelmator is a solid choice for just about any designer; it provides a lot of the power and functionality of Adobe Photoshop at a fraction of the price.

To me, Pixelmator feels like a tool that was born from the attitude “Let’s make a tool that does 80% of what people use Photoshop for, and get rid of the more complicated stuff most people don’t use.” That ease of use, coupled with powerful features, is why Pixelmator is a favorite with many members of the raywenderlich.com team.

Pixelmator is easy to learn, and you’ll likely find that for every task you perform in Photoshop, that same task is a little easier in Pixelmator. For developers who occasionally need an image editing tool, it’s probably the best choice given the balance of cost and functionality.

So why is it listed behind Photoshop, in spite of being a better choice for many? Read on to find out! :]

2. Photoshop

Price: $9.99 per month for Adobe Photoshop and Lightroom as part of the Creative Cloud Photography plan.
Pros: The most powerful and most-used raster graphics editor; easy to find tutorials and guides online.
Cons Steep learning curve; resource hog; recurring cost as long as you want to keep it around.

Getting Photoshop

It’s unlikely you’ll ever see Adobe’s products in the Mac App Store; you can only purchase Adobe Photoshop through a subscription. Adobe’s least expensive plan that includes Photoshop is the $9.99 per month Creative Cloud Photography plan. Other plans are available, ranging up to the All Apps plan that includes all Adobe apps for $49.99 per month.

However, there is a trial version of Photoshop availble for download as well.

Building the Image in Photoshop

Start Photoshop, then select File\Open and choose Twitter_card_bg_image.png. Next, select File\Open and choose Twitter_card_overlay.png image.

You’ll need to adjust the background image to fit your final image size. Select Image\Image Size…; ensure the small link icon is selected and light gray lines run from it to the two size parameters. This is your indicator that Photoshop will preserve your image ratio.

Enter a Width of 640 pixels to match your desired final image width and the height will automatically adjust o 400. Click OK to resize the image.

Step 2

Copy the entire resized background image to the clipboard: select Select\All or press Command-A, then select Edit\Copy or press Command-C. Next, select the window containing your overlay image and paste the background image from the clipboard as a new layer by selecting Edit\Paste or pressing Command-V.

The overlay layer is currently hidden underneath your background layer. Drag the overlay layer above the background layer in the Layers list, like so:
Step 5

Photoshop placed the new layer aligned with the top of the image, so you’ll need to align the images at their centers. You can use Photoshop’s Smart Guides to easily align the image.

Go to View\Show and ensure Smart Guides is checked. Select the pasted layer and select the Move Tool. Hold down Shift to contrain your movements to right angles and 45-degree angles, then click on the image and drag it upward.

When the image is centered, you’ll see the purple Smart Guides appear, as shown below:

Step 4

Now for the text. Click on the Horizontal Text Tool. In the toolbar, change the Font to Open Sans Regular and enter 26 for the text size. Click near the bottom-left corner of the overlay and enter Such Tutorials Much Wow.

Use the Move Tool to adjust the position of the text to your liking:

Step 6

To add the outer stroke to the text, double-click on an empty section of the text layer to open the Layer Style window. Check the Stroke option, set the Size to 3 px and the Position to Outside.

Click the black default color and drag the brightness slider all the way up upward to change the color to white. Click OK to save and apply these changes. Your finished image should look like the following:

Step 7

Why Use Photoshop?

Photoshop has a long history with the Mac and is one of the reasons Macs found a home with designers and artists. Adobe long ago set the standard for graphics and design tools. New tools compare themselves to Adobe and even handle Adobe file formats. When I work with a designer, the results often arrive as Photoshop PSD file.

So then why is Photoshop number two on this list? It’s by far the most powerful tool for working with raster images. If an experienced Photoshop user can’t do something in Photoshop, you probably can’t do it in any editor. And If you don’t know how to do something in Photoshop, it’s easy to find multiple tutorials or videos online to help you out.

You shouldn’t use Photoshop just because it’s been around a long time, however. A tool should work for you — not just because everyone uses it.

I’ve used Photoshop for nineteen years, so I’ve learned how to quickly take care of my tasks in the app. The UI carries a lot of baggage and isn’t intuitive for new users. When I need to do something that’s not part of my standard workflow, looking it a solution online is usually faster than trying to figure it out on my own.

Learning Photoshop takes dedication and time, and in truth, I think Photoshop is so complex that you’d be hard-pressed to find a single person who fully understands everything it can do.

A designer will need a lot of the features in Photoshop, but for light editing, resizing, and cropping tasks, it’s probably more power than you need and you’d be just as happy with a less expensive tool such as Pixelmator.

Even if you don’t need all the features of Photoshop, it might still have a place in your toolbox. There’s a steep investment in learning Photoshop, but that investment will pay you back over years to come. I’ve tried other tools, and I still come back to Photoshop for most of my needs.

And the number one choice as picked by the raywenderlich.com team is…

1. Sketch

Price: $99.99.
Pros: Best tool for UI/UX design; good mockup and prototyping tool; extendable.
Cons: No longer in App Store; not the best tool for image manipulation.

Getting Sketch

Sketch recently left the Mac App Store; the only way to get the app is from the company’s web site.

You can download a trial version from their site, unzip the package and drag the Sketch.app file to your Applications folder to install.

Building the Image in Sketch

Select File\Open and open Twitter_card_bg_image.png. Your first task is to resize the image to match your desired final image size. The small lock between the width and height fields shows that Sketch will preserve your aspect ration. Change the width to 640 and the height will adjust to 400 to match:

Step 1

Now to load the overlay image. Select Insert\Image… and choose Twitter_card_overlay.png. Sketch adds the new image as a new layer above the background image. Drag the overlay layer to center the overlay above the background image, like so:

Step 2

Next you’ll need to use a mask to clip the background image to match the overlay.

Select the background layer with the background image and click the Mask button in the toolbar. This creates a new group consisting of the image on this layer and the new mask. By default, the mask matches the height of your overlay but cuts off more of the sides of our background image than you want.

Click on the small white square on the left edge of the mask and drag it all the way to the left side of the overlay. A red line will appear to highlight when you’ve reached the left edge. Next, drag the small white square on the right side of the mask to the right of the overlay:

Step 3

Now you can add some text. Click the Insert button in the toolbar and select Text from the dropdown menu. Click in the bottom left corner of the frame and enter Such Tutorials Much Wow.

With the text layer still selected, change the Typeface to Open Sans. Note that Sketch provides a search menu for fonts, which is useful for those developers with tons of installed fonts — you know who you are! :] Finally, enter 26 for the text size:

Step 4

Adding an outside stroke to text isn’t a simple operation in Sketch; you can’t use an Outside border on a text layer, which makes it difficult to add the outer stroke. You could convert the text to a shape layer and apply an Outside border, but that effect doesn’t quite match what you’re looking for, so you’ll skip that step.

Your finished image should look like the following:

Sketch Final Image

Why Use Sketch?

Sketch earned the top spot on this list because it feels like a natural tool for UI and UX design. I’ve never found another tool that let you create and manipulate complex designs with such ease. The magic of good app design comes from building great UI and UX, and Sketch does that better than any other app for developers working on the Apple platform.

Sketch is a vector based tool; you’ll find it greatly eases building layouts and designs. The built-in UI templates make designing apps and iOS or Mac icons a breeze. It’s easy to iterate and evolve my designs, and when I have what I want, Sketch can assemble and export those assets at 1x, 2x, and 3x resolutions. There’s also a rich plugin infrastructure that adds additional functionality without cluttering the main app.

While Sketch works wonderfully with vector drawing, it’s not the only tool you’ll ever need. For working with raster images, you’re better off with Photoshop or Pixelmator. It’s also a bit more unstable and buggy than I’d expect for such a powerful tool.

Sketch’s popularity means you’ll find a lot of resources to help you learn Sketch. The Sketch web site provides several tutorial videos and also maintains a list of off-site courses and articles. I’d recommend our recent Sketch tutorial by Robert Chen for a good, in-depth introduction to Sketch.

Which Editor Is the Right One for Me?

Each image editor in this list has its own strengths and weaknesses, and depending on your needs, you might find you need more than one tool to get the job done.

Here’s a good guideline to help you choose the right tool for your needs:

  • If you’re looking for a tool for UI or UX design or app prototyping, you can’t beat Sketch. It’s a favorite on the raywenderlich.com team and among many other developers.
  • If Sketch looks appealing, but you’d like something less expensive, you’ll find Affinity Designer a good choice. Affinity Designer also makes a good general design tool or a replacement for Adobe Illustrator.
  • If you need to work with custom controls and dynamic graphics, the code generation feature of PaintCode will make an excellent addition to your workflow.
  • If you are doing raster image editing and need a tool you’ll use a few times a month, Pixelmator will suit your needs just fine. It’s an amazingly powerful app for the price, and can handle most of what you’ll likely ask it to do.
  • If you want the gold standard, then Photoshop may be for you. Photoshop is a complex tool, but that complexity comes from its sheer power. The recurring subscription costs add up over time, but when you’re managing complex images and you use a tool every day for hours at a time, Paintshop is your best choice. Combining it with Sketch gives you the best combination of vector and raster tools possible for developers.

Hopefully this list of image editors helps you out in your quest to find the perfect tool to fit your needs. Do you have any experiences to share in your own work with these tools? Join the discussion below and share your thoughts with the community!

The post Best Image Editors for OS X appeared first on Ray Wenderlich.

Video Tutorial: Beginning watchOS Part 8: Drawing with Core Graphics

Video Tutorial: Beginning watchOS Part 9: Animations


Video Tutorial: Beginning watchOS Part 10: Glances

Video Tutorial: Beginning watchOS Part 11: Conclusion

Video Tutorial: Advanced watchOS: Series Introduction

Video Tutorial: Advanced watchOS Part 1: Layout

Video Tutorial: Advanced watchOS Part 2: Tables & Table Rows

Push Notifications Tutorial: Getting Started

$
0
0
push notifications tutorial

Learn how to get started with push notifications!

iOS developers love to imagine users of their awesome app using the app all day, every day. Unfortunately, the cold hard truth is that users will sometimes have to close the app and perform other activities. Laundry doesn’t fold itself, you know :]

Happily, push notifications allow developers to reach users and perform small tasks even when users aren’t actively using an app!

Push notifications have become more and more powerful since they were first introduced. In iOS 9, push notifications can:

  • Display a short text message
  • Play a notification sound
  • Set a badge number on the app’s icon
  • Provide actions the user can take without opening the app
  • Be silent, allowing the app to wake up in the background and perform a task

This push notifications tutorial will go over how push notifications work, and let you try out their features.

Before you get started, you will need the following to test push notifications:

  • An iOS device. Push notifications do not work in the simulator, so you’ll need an actual device.
  • An Apple Developer Program Membership. Since Xcode 7, you can now test apps on your device without a program membership. However, to configure push notifications you need a push notification certificate for your App ID, which requires the program membership.

Getting Started

There are three main tasks that must be performed in order to send and receive a push notification:

  1. The app must be configured properly and registered with the Apple Push Notification Service (APNS) to receive push notifications upon every start-up.
  2. A server must send a push notification to APNS directed to one or more specific devices.
  3. The app must receive the push notification; it can then perform tasks or handle user actions using callbacks in the application delegate.

Tasks 1 and 3 will be the main focus of this push notifications tutorial, since they are the responsibility of an iOS developer.

Task 2 will also be briefly covered, mostly for testing purposes. Sending push notifications is a responsibility of the app’s server-component and is usually implemented differently from one app to the next. Many apps use third-parties (ex. Parse.com or Google Cloud Messaging) to send push notifications, while others use custom solutions and/or popular libraries (ex. Houston).

To get started, download the starter project of WenderCast. WenderCast is everyone’s go-to source for raywenderlich.com podcasts and breaking news.

Open WenderCast.xcodeproj in Xcode and take a peek around. Build and run to see the latest podcasts:

push notifications tutorial

The problem with the app is that it doesn’t let users know when a new podcast is available. It also doesn’t really have any news to display. You’ll soon fix all that with the power of push notifications!

Configuring an App for Push Notifications

Push notifications require a lot of security. This is quite important, since you don’t want anyone else to send push notifications to your users. What this means is that there are quite a few hoops to jump through to configure apps for push notifications.

Enabling the Push Notification Service

The first step is to change the App ID. Go to App Settings -> General and change Bundle Identifier to something unique:

push notifications tutorial

Next, you need to create an App ID in your developer account that has the push notification entitlement enabled. Luckily, Xcode has a simple way to do this. Go to App Settings -> Capabilities and flip the switch for Push Notifications to On.

After some loading, it should look like this:

push notifications tutorial

Behind the scenes, this creates the App ID in your member center if it doesn’t exist already, then adds the push notifications entitlement to it. You can log in and verify this:

push notifications tutorial

If any issues occur, manually create the App ID or add the push notifications entitlement in the member center by using the + or Edit buttons.

That’s all you need to configure for now.

Registering for Push Notifications

There are two steps to register for push notifications. First, you must obtain the user’s permission to show any kind of notification, after which you can register for remote notifications. If all goes well, the system will then provide you with a device token, which you can think of as an “address” to this device.

In WenderCast, you will register for push notifications immediately after the app launches.

Open AppDelegate.swift and add the following method to the end of AppDelegate:

func registerForPushNotifications(application: UIApplication) {
  let notificationSettings = UIUserNotificationSettings(
    forTypes: [.Badge, .Sound, .Alert], categories: nil)
  application.registerUserNotificationSettings(notificationSettings)
}

This method creates an instance of UIUserNotificationSettings and passes it to registerUserNotificationSettings(_:).

UIUserNotificationSettings stores settings for the type of notification your app will use. For the UIUserNotificationTypes, you can use any combination of the following:

  • .Badge allows the app to display a number on the corner of the app’s icon.
  • .Sound allows the app to play a sound.
  • .Alert allows the app to display text.

The set of UIUserNotificationCategorys that you currently pass nil to allows you to specify different categories of notifications your app can handle. This becomes necessary when you want to implement actionable notifications, which you will use later.

Add a call to registerForPushNotifications(_:) as the first line in application(_:didFinishLaunchingWithOptions:launchOptions:):

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  registerForPushNotifications(application)
  //...
}

Build and run. When the app launches, you should receive a prompt that asks for permission to send you notifications:

push notifications tutorial

Tap OK and poof! The app can now display notifications. Great! But what now? What if the user declines the permissions?

When the user accepts or declines your permissions or has already made that selection in the past, a delegate method of UIApplicationDelegate gets called. Add this method inside AppDelegate:

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
 
}

In this method, you get passed another UIUserNotificationSettings. This one is very different from the previous one you passed in. That one specified the settings you want, while this one specifies the settings the user has granted.

It’s extremely important to call registerUserNotificationSettings(_:) every time the app launches. This is because the user can, at any time, go into the Settings app and change the notification permissions. application(_:didRegisterUserNotificationSettings:) will always provide you with what permissions the user currently has allowed for your app.

Step 1 is now complete, and you can now register for remote notifications. This is slightly easier, since you don’t need more permissions from the user. Update application(_:didRegisterUserNotificationSettings:) with the following:

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
  if notificationSettings.types != .None {
    application.registerForRemoteNotifications()
  }
}

Here, you first check whether the user has granted you any notification permissions; if they have, you directly call registerForRemoteNotifications().

Again, methods in UIApplicationDelegate are called to inform you about the status of registerForRemoteNotifications().

Add the following two methods to AppDelegate:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
  let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
  var tokenString = ""
 
  for i in 0..<deviceToken.length {
    tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
  }
 
  print("Device Token:", tokenString)
}
 
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
  print("Failed to register:", error)
}

As the names suggest, the system calls application(_:didRegisterForRemoteNotificationsWithDeviceToken:) when the registration is successful, and otherwise calls application(_:didFailToRegisterForRemoteNotificationsWithError:).

The current implementation of application(_:didRegisterForRemoteNotificationsWithDeviceToken:) looks cryptic, but it is simply taking deviceToken and converting it to a string. The device token is the fruit of this process. It is a token provided by APNS that uniquely identifies this app on this particular device. When sending a push notification, the app uses device tokens as “addresses” to direct notifications to the correct devices.

Note: There are several reasons why registration might fail. Most of the time it’s because the app is running on a simulator, or because the App ID configuration was not done properly. The error message generally provides a good hint as to what is wrong.

That’s it! Build and run. Make sure you are running on a device, and you should receive a device token in the console output. Here’s what mine looks like:

push notifications tutorial

Copy this token somewhere handy.

You have a bit more configuration to do before you can send a push notification, so return to Apple’s Developer Member Center.

Creating an SSL Certificate and PEM file

In your member center, go to Certificates, Identifiers & Profiles -> Identifiers -> App IDs and find the App ID for your app. Under Application Services, Push Notifications should be Configurable:

push notifications tutorial

Click Edit and scroll down to Push Notifications:

push notifications tutorial

In Development SSL Certificate, click Create Certificate… and follow the steps to create a CSR. Once you have your CSR, click continue and Generate your certificate using the CSR. Finally, download the certificate and run it, which should add it to your Keychain, paired with a private key:

push notifications tutorial

Back in the member center, your App ID should now have push notifications enabled for development:

push notifications tutorial

There is one last thing you need before you close Keychain Access. Right-click on your new push certificate and choose Export:

push notifications tutorial

Save it as WenderCastPush.p12 to Desktop as a .p12 file:

push notifications tutorial

You will be prompted to enter a password for the p12. You can either leave this blank or enter a password of your choosing. I used “WenderCastPush” as the password. You’ll then need to enter your log-in password to permit the export.

Next, open up your terminal and run the following commands to generate a PEM file from the p12 file:

$ cd ~/Desktop
$ openssl pkcs12 -in WenderCastPush.p12 -out WenderCastPush.pem -nodes -clcerts

If you created a password for the p12 file, you will need to enter it here.

Whew! That was a lot to get through, but it was all worth it — with your new WenderCastPush.pem file, you are now ready to send your first push notification!

Sending a Push Notification

The starter kit includes a folder called WenderCastPush; inside are two simple scripts that send push notifications. The one you will be using is newspush.php. As its name suggests, this script sends breaking news to your users.

Sending push notifications requires an SSL connection to APNS, secured by the push certificate you just created. That’s where WenderCastPush.pem comes in. Rename WenderCastPush.pem to ck.pem and replace the existing ck.pem in the WenderCastPush folder.

Open newspush.php and update $deviceToken to the one you received earlier, and $passphrase to the password you gave your push certificate when exporting:

// Put your device token here (without spaces):
$deviceToken = '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69';
 
// Put your private key's passphrase here:
$passphrase = 'WenderCastPush';

Open your terminal, cd to the folder containing newspush.php and type:

$ php newspush.php 'Breaking News' 'https://raywenderlich.com'

If all goes well, your terminal should display:

Connected to APNS
Message successfully delivered

You should receive your first push notification:

push notifications tutorial

Note: You won’t see anything if the app is open and running in the foreground. The notification is delivered, but there’s nothing in the app to handle it yet. Simply close the app and send the notification again.

Common Issues

There are a couple problems that might arise:

Some notifications received but not all: If you’re sending multiple push notifications simultaneously and only a few are received, fear not! That is intended behaviour. APNS maintains a QoS (Quality of Service) queue for each device with a push app. The size of this queue is 1, so if you send multiple notifications, the last notification is overridden.

Problem connecting to Push Notification Service: One possibility could be that there is a firewall blocking the ports used by APNS. Make sure you unblock these ports. Another possibility might be that the private key and CSR file are wrong. Remember that each App ID has a unique CSR and private key combination.

Anatomy of a Basic Push Notification

Before you move on to Task 3, handling push notifications, take a look at newspush.php to get a basic idea of what a push notification looks like.

Pay attention to lines 32-40. Here the payload body is created and encoded as JSON. This is what actually gets sent to APNS. In this case, the payload looks like this:

{
  "aps":
  {
    "alert": "Breaking News!",
    "sound": "default"
    "link_url" : "https://raywenderlich.com,
  }
}

For the JSON-uninitiated, a block delimited by curly { } brackets contains a dictionary that consists of key/value pairs (just like an NSDictionary).

The payload is a dictionary that contains at least one item, aps, which itself is also a dictionary. In this example, “aps” contains the fields “alert,” “sound,” and “link_url.” When this push notification is received, it shows an alert view with the text “Breaking News!” and plays the standard sound effect.

“link_url” is actually a custom field. You can add custom fields to the payload like this and they will get delivered to your application. Since you aren’t handling it inside the app yet, this key/value pair currently does nothing.

There are five keys you can add to the aps dictionary:

  • alert. This can be a string, like in the previous example, or a dictionary itself. As a dictionary, it can localize the text or change other aspects of the notification. See Apple’s documentation for all the keys it can support.
  • badge. This is a number that will display in the corner of the app icon. You can remove the badge by setting this to 0.
  • sound. By setting this key, you can play custom notification sounds located in the app in place of the default notification sound. Custom notification sounds must be shorter than 30 seconds and have a few restrictions, which you can see in Apple’s documentation.
  • content-available. By setting this key to 1, the push notification becomes a silent one. This will be explored later in this push notifications tutorial.
  • category. This defines the category of the notification, which is is used to show custom actions on the notification. You will also be exploring this shortly.

Outside of these, you can add as much custom data as you want, as long as the payload does not exceed the maximum size of 4096 bytes.

Once you’ve had enough fun sending push notifications to your device, move on to the next section. :]

Handling Push Notifications

In this section, you’ll learn how to perform actions in your app when push notifications are received and/or when users tap on them.

What Happens When You Receive a Push Notification?

When your app receives a push notification, a method in UIApplicationDelegate is called.

The notification needs to be handled differently depending on what state your app is in when it’s received:

  • If your app wasn’t running and the user launches it by tapping the push notification, the push notification is passed to your app in the launchOptions of application(_:didFinishLaunchingWithOptions:).
  • If your app was running and in the foreground, the push notification will not be shown, but application(_:didReceiveRemoteNotification:) will be called immediately.
  • If your app was running or suspended in the background and the user brings it to the foreground by tapping the push notification, application(_:didReceiveRemoteNotification:) will be called.

In the first case, WenderCast will create the news item and open up directly to the news section. Add the following code to the end of application(_:didFinishLaunchingWithOptions:), before the return statement:

// Check if launched from notification
// 1
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
  // 2
  let aps = notification["aps"] as! [String: AnyObject]
  createNewNewsItem(aps)
  // 3
  (window?.rootViewController as? UITabBarController)?.selectedIndex = 1
}

This code does three things:

  1. It checks whether the value for UIApplicationLaunchOptionsRemoteNotificationKey exists in launchOptions. If it does, this will be the push notification payload you sent.
  2. If it exists, you grab the aps dictionary from it and pass it to createNewNewsItem(_:), which is a helper method provided to create a NewsItem from the dictionary and refresh the news table.
  3. Changes the selected tab of the tab controller to 1, the news section.

To test this, you need to edit the scheme of WenderCast:

push notifications tutorial

Under Run -> Info, select Wait for executable to be launched:

push notifications tutorial

This option will make the debugger wait for the app to be launched for the first time after installing to attach to it.

Build and run. Once it’s done installing, send out some breaking news again. Tap on the notification, and the app should open up to some news:

push notifications tutorial

Note: If you stop receiving push notifications, it is likely that your device token has changed. This can happen if you uninstall and reinstall the app. Double check the device token to make sure.

To handle the other two cases, add the following method to AppDelegate:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
  let aps = userInfo["aps"] as! [String: AnyObject]
  createNewNewsItem(aps)
}

This method directly uses the helper function to create a new NewsItem. You can now change the scheme back to launching the app automatically if you like.

Build and run. Keep the app running in the foreground and on the News section. Send another news push notification and watch as it magically appears in the feed:

push notifications tutorial

That’s it! Your app can now handle breaking news in this basic way.

Something important thing to note: many times, push notifications may be missed. This is ok for WenderCast, since having the full list of news isn’t too important in this app, but in general you should not use push notifications as the only way of delivering content. Instead, push notifications should signal that there is new content available and let the app download the content from the source. WenderCast is a bit limited in this sense, as it doesn’t have a proper server-side component.

Actionable Notifications

Actionable notifications let you add custom buttons to the notification itself. You may have noticed this on email notifications or Tweets that let you “reply” or “favorite” on the spot.

Actionable notifications are defined by your app when you register for notifications by using categories. Each category of notification can have a few preset custom actions.

Once registered, your server can set the category of a push notification; the corresponding actions will be available to the user when received.

For WenderCast, you will define a “News” category with a custom action “View” which allows users to directly view the news article in the app if they choose to.

Add the following code to the beginning of registerForPushNotifications(_:):

let viewAction = UIMutableUserNotificationAction()
viewAction.identifier = "VIEW_IDENTIFIER"
viewAction.title = "View"
viewAction.activationMode = .Foreground

This creates a new notification action with the title View on the button, and opens the app into the foreground when triggered. The action has the identifier VIEW_IDENTIFIER, which is used to differentiate between different actions on the same notification.

Add the following snippet right after the previous one:

let newsCategory = UIMutableUserNotificationCategory()
newsCategory.identifier = "NEWS_CATEGORY"
newsCategory.setActions([viewAction], forContext: .Default)

This defines the news category with the view action for a default context. The identifier NEWS_CATEGORY is what your payload will need to contain to specify that the push notification belongs to this category.

Finally, pass it into the constructor for UIUserNotificationSettings by changing the existing line to:

let notificationSettings = UIUserNotificationSettings(forTypes: [.Badge, .Sound, .Alert], categories: [newsCategory])

That’s it! Build and run the app to register the new notification settings. Press the home button to close the app so the push notification will be visible.

Before you run newspush.php again, first perform a small modification to specify the category. Open newspush.php and modify the payload body to include the category:

$body['aps'] = array(
  'alert' => $message,
  'sound' => 'default',
  'link_url' => $url,
  'category' => 'NEWS_CATEGORY',
  );

Save and close newspush.php, then run it to send another push notification. If all goes well, you should be able to pull down or swipe on the notification to reveal the View action:

push notifications tutorial

Nice! Tapping on it will launch WenderCast but not do anything. To get it to display the news item, you need to do some more event handling in the delegate.

Handling Notification Actions

Back in AppDelegate.swift, add another method:

func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
  // 1
  let aps = userInfo["aps"] as! [String: AnyObject]
 
  // 2
  if let newsItem = createNewNewsItem(aps) {
    (window?.rootViewController as? UITabBarController)?.selectedIndex = 1
 
    // 3
    if identifier == "VIEW_IDENTIFIER", let url = NSURL(string: newsItem.link) {
      let safari = SFSafariViewController(URL: url)
      window?.rootViewController?.presentViewController(safari, animated: true, completion: nil)
    }
  }
 
  // 4
  completionHandler()
}

This is the callback you get when the app is opened by a custom action. It might look like there’s a lot going on, but there’s really not much new here. The code:

  1. Gets the aps dictionary.
  2. Creates the NewsItem from the dictionary and goes to the News section.
  3. Checks the action identifier, which is passed in as identifier. If it is the “View” action and the link is a valid URL, it displays the link in a SFSafariViewController.
  4. Calls the completion handler that is passed to you by the system after handling the action.

Build and run. Close the app again, then send another news notification. Make sure the URL is valid:

$ php newspush.php 'New Posts!' 'https://raywenderlich.com'

Tap on the action, and you should see WenderCast present a Safari View Controller right after it launches:

push notifications tutorial

Congratulations, you’ve just implemented an actionable notification! Send a few more and try opening the notification in different ways to see how it behaves.

Silent Push Notifications

Silent push notifications can wake your app up silently to perform some tasks in the background. WenderCast can use this feature to quietly refresh the podcast list.

As you can imagine, with a proper server-component this can be very efficient. Your app won’t need to poll for data constantly — you can send it a silent push notification whenever new data is available.

To get started, go to App Settings -> Capabilites and turn on Background Modes for WenderCast. Check the last option, Remote Notifications:

push notifications tutorial

Now your app will wake up in the background when it receives one of these push notifications.

Inside AppDelegate, replace application(_:didReceiveRemoteNotification:) with this more powerful version:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
  let aps = userInfo["aps"] as! [String: AnyObject]
 
  // 1
  if (aps["content-available"] as? NSString)?.integerValue == 1 {
    // Refresh Podcast
    // 2
    let podcastStore = PodcastStore.sharedStore
    podcastStore.refreshItems { didLoadNewItems in
      // 3
      completionHandler(didLoadNewItems ? .NewData : .NoData)
    }
  } else  {
    // News
    // 4
    createNewNewsItem(aps)
    completionHandler(.NewData)
  }
}

This code:

  1. Checks to see if content-available is set to 1, to see whether or not it is a silent notification.
  2. Refreshes the podcast list, which is a network call and therefore asynchronous.
  3. When the list is refreshed, calls the completion handler and lets the system know whether any new data was loaded.
  4. If it isn’t a silent notification, assumes it is news again and create a news item.

Be sure to call the completion handler and be honest about the result. The system measures the battery consumption and time that your app uses in the background, and may throttle you if needed.

That’s all there is to it; now you can use contentpush.php to send the silent push notification to your app. Make sure to modify the settings of that script as well:

// Put your device token here (without spaces):
$deviceToken = '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69';
 
// Put your private key's passphrase here:
$passphrase = 'WenderCastPush';

Directly run it in the terminal:

$ php contentpush.php

If all goes well, nothing should happen! To see the code being run, change the scheme to “Wait for executable to be launched” again and set a breakpoint within application(_:didReceiveRemoteNotification:fetchCompletionHandler:) to make sure it runs.

Where To Go From Here?

Congrats — you’ve completed this push notifications tutorial and made WenderCast a fully-featured app with push notifications!

You can download the completed project here. Remember that you will still need to change the bundle ID and create certificates to make it work.

Even though push notifications are an important part of apps nowadays, it’s also very common for users to decline permissions to your app if notifications are sent too often. But with thoughtful design, push notifications can keep your users coming back to your app again and again!

push notifications tutorial

This cat received a push notification that his dinner was ready

I hope you’ve enjoyed this push notifications tutorial; if you have any questions feel free to leave them in the discussion below.

The post Push Notifications Tutorial: Getting Started appeared first on Ray Wenderlich.

Video Tutorial: Advanced watchOS Part 3: Pickers & Text Entry


Video Tutorial: Advanced watchOS Part 4: Watch Connectivity I

Video Tutorial: Advanced watchOS Part 5: Watch Connectivity II

Announcing 3D iOS Games by Tutorials Week!

$
0
0

3D iOS Games by Tutorials Week

For the past 9 months, tutorial team member Chris Language has been working on a secret project: 3D iOS Games by Tutorials.

Today, we have some exciting news – the book is now 100% complete and is available today!

In 3D iOS Games by Tutorials, you’ll learn how to make 3D games in Swift, using Apple’s built-in game framework: Scene Kit. You’ll learn how to make games similar to Fruit Ninja, Breakout, Marble Madness, and Crossy Road.

To celebrate the book launch, this week we’ll be posting a few chapters, and giving away a few free copies of the book.

Keep reading to watch a video trailer for the book, how to enter the giveaway, and how to get your launch discount!

Book Trailer

The best way to understand the book is to watch our official book trailer:

Pretty cool, eh? :]

Introducing 3D iOS Games by Tutorials

3D iOS Games by Tutorials is 20 chapters and 378 pages, split into four sections and moves from beginning to advanced topics. In each section, you will create a complete mini-game from scratch!

Let’s take a look at what’s ahead.

Section I: Hello, SceneKit!

This section covers the basics of making 3D games with SceneKit. You’ll look at the most important techniques used in almost every 3D SceneKit game created, and by the end of this section you’ll know enough to make your very own little 3D game: Geometry Fighter.

This is a Fruit Ninja style game, with colorful geometric shapes thrown up into the air for your pure destructive indulgence. Seek out your inner Darth Vader and use the force to destroy the colorful shapes with a single touch of death! :]

00_ScreenShot

  1. Chapter 1, Scenes: Start off by creating your very first SceneKit game project, and get to know the basics.
  2. Chapter 2, Nodes: Learn how to use nodes, primitive geometry shapes and cameras to construct a basic 3D scene from the ground up.
  3. Chapter 3, Physics: Unleash the power of the built-in physics engine, and learn how to add basic physics to the elements in your game.
  4. Chapter 4, Render Loop: Learn all about the render loop within SceneKit, and how you can leverage it to update the elements in your game.
  5. Chapter 5, Particle Systems: Create massive explosions for your game, by learning how to create and use the 3D particle system.

Section II: The SceneKit Editor

Xcode include a variety of standard built-in tools; in this section, you’ll take an in-depth look at them. These tools will make building your 3D games with SceneKit easier, faster and even more fun.

Throughout this section you’ll be making a game called Breaker, which is based on Breakout, but it adds a nice new 3D look and feel. Keep your paddle and ball close by, so you can go bust up some bricks! :]

06_ScreenShot

  1. Chapter 6, Scene Editor: Get a hands-on introduction on how to use Xcode’s awesome built-in SceneKit Editor.
  2. Chapter 7, Cameras: Learn about the different types of cameras SceneKit has to offer.
  3. Chapter 8, Lights: Learn all about the different types of lights, and how to properly set them up for your game.
  4. Chapter 9, Primitives: Get your hands dirty and construct the entire game scene with just using the built-in SceneKit primitive shapes.
  5. Chapter 10, Basic Collision Detection: Add physics to your game and learn how to handle basic collision detection.

Section III: Intermediate SceneKit

In this section you will create stunning a make belief world, with a shiny wooden relic awaits brave warriors with exceptional balancing skills to guide it through a maze high up in the sky. The game is called Marble Maze, and is somewhat based on the Labyrinth styled games with a twist.

11_Screenshot

  1. Chapter 11, Materials: Learn about the different lighting models and the various material types supported by SceneKit.
  2. Chapter 12, Reference Nodes: Learn how to start using reference nodes in your game.
  3. Chapter 13, Shadows: Learn how to use and configure the darker element of light, known as shadows.
  4. Chapter 14, Intermediate Collision Detection: Learn all about bit masks and how to make use of them for more intermediate collision detection scenarios.
  5. Chapter 15, Motion Control: Add motion control to your game, and learn how to use the motion data to move the elements in your game.

Section IV: Advanced SceneKit

“The SceneKit Force is quite strong within you, young apprentice.” (Read in a deep, heavy, asthmatic breathing voice. :] )

In this section, you’ll learn few more advanced techniques, as well as apply all the skills you’ve learned up to this point, to creating an awesome little voxel style game. By the end of this section, you’ll know enough to take on the big Hipster Whales out there with your very own game: Mr. Pig.

16_Screenshot

This is a Crossy Road style game with stunning voxel graphics, a catchy tune and some cool sound effects.

The premise: Mr. Pig is out-and-about scouting for lost coins in a nearby park while waiting for his late afternoon tea to heat up on the stove. Unfortunately, some big bad wolf decided to build a massive mall nearby, resulting in a very busy highway straight through his lovely park.

Mr. Pig better watch his step, or he’ll end up as pulled pork in the road. :] Our hero can carry quite a few coins with him, but to score, he has to deposit them at his little house.

No need to get your tail in a twist or ham it up — we’ll walk you through every step of building the game!

  1. Chapter 16, Transitions: Create multiple scenes and learn how to transition from one to the other.
  2. Chapter 17, Advanced Reference Nodes: Start building more complex scenes by leveraging the power of reference nodes to make scene-building child’s play.
  3. Chapter 18, Actions: Learn how to add basic animation to the elements in your game by using Xcode’s built-in action editor.
  4. Chapter 19, Advanced Collision Detection: Learn how to use more advanced collision techniques to solve certain scenarios.
  5. Chapter 20, Audio: Harness SceneKit’s built-in sound capabilities to play music, sound effects and ambient sounds.

3D iOS Games by Tutorials Week and Giveaway

calendar-igt2

Today, we are launching the book, and from Tuesday to Thursday, we’ll be releasing the first 5 chapters from the book as free tutorials on this site. This will give you a chance to check out the book – we’re confident you’ll love it! :]

On Friday, we’ll round out our week of celebration with a special giveaway. 3 lucky winners will win a free PDF copy of 3D iOS Games by Tutorials (or a book of your choice if you already have 3D iOS Games by Tutorials).

To enter into this giveaway, simply leave a comment on this post. We’ll choose winners randomly and announce the results on Friday.

Where To Go From Here?

As mentioned, 3D iOS Games by Tutorials is now 100% complete and available today.

Also, we have some good news! To celebrate the launch week, we are offering the book at a $10 off discount until this Friday.

If you want the special discount, be sure to order now.

Chris and I hope you enjoy 3D iOS Games by Tutorials, and look forward to seeing some amazing 3D iOS Games from you!

The post Announcing 3D iOS Games by Tutorials Week! appeared first on Ray Wenderlich.

Video Tutorial: Advanced watchOS Part 6: Notifications

Scene Kit Tutorial with Swift Part 1: Getting Started

$
0
0
Note: This is an abbreviated chapter from the 3D iOS Games by Tutorials, to give you a sneak peek of what’s inside the book, released as part of 3D iOS Games by Tutorials Week. We hope you enjoy!

Thumb

This tutorial series will show you how to create your first game with Scene Kit, Apple’s built-in 3D game framework.

You’d be forgiven for thinking that making 3D games is far more complicated than creating a classic 2D game. 3D games have a reputation for being notoriously difficult to program, usually involving a lot of complicated math.

However, that is no longer the case, thanks to the advent of Apple’s Scene Kit! The simplicity of Scene Kit lets beginners create simple and stylish games in a short amount of time.

In this 5-part Scene Kit tutorial series, you’ll create your first Scene Kit game: Geometry Fighter. This is a Fruit Ninja style game, with colorful geometric shapes thrown up into the air for your pure destructive indulgence.

In this first part of the series, you’ll simply create a blank project to have a good starting point, which is good for people who like to understand every step. If you’d prefer to dive right into coding, skip to part 2 of this series, where we’ll have a starter project ready for you.

Getting Started

Open up Xcode and select File\New\Project from the main menu. If you want to become an Xcode ninja, use the shortcut command: ⇧⌘N.

Select the iOS\Application\Game template and click Next to continue:

CreateProject00

Now you need to provide some basic details about your project. Enter GeometryFighter for the Product Name, select Swift for Language, SceneKit for Game Technology, Universal for Devices, uncheck the unit tests and click Next:

CreateProject01

The final step is to choose a convenient location to save your project. Pick a directory and select Create; Xcode will work its magic and generate your project.

Building Your Scene Kit Game Project

Now that you’ve generated your Scene Kit game project from the template, you’d probably like to see it in action! :]

First, choose the iPhone 6 simulator from the toolbar, then press the Play button at the top to build and run your project. Xcode ninjas can simply press ⌘R:

CreateProject02

You’ll see the simulator spin up, and your first 3D Scene Kit game will appear. You can rotate the view of your 3D spaceship in the game. Simply drag around the screen in different directions to change the camera angle:

BuildAndRun00

Cool! It’s okay to take a moment and do a little happy dance in your seat, then continue on with the rest of the tutorial.

Cleaning Up Your Game Project

There are a few components you need to remove in order to start with a clean Scene Kit game project. Don’t worry; you’ll re-create all the content from scratch so you can learn where it comes from.

Removing Unnecessary Folders

The first thing to get rid of is the art.scnassets folder. Right click the folder, select Delete and then click Move to Trash:

DeleteSCNAssetsFolder00

Note: Don’t worry too much about the purpose of the art.scnassets folder now. Just know that the Xcode Scene Kit game template generated art.scnassets for you automatically. It’s always a good idea to keep your project free of any cruft.

Cleaning Up the Main Project Files

The GameViewController.swift file is a key component of your game; it’s where all your game logic and code will live. Before you can start coding, you need to purge all the code the Xcode Scene Kit game template created for you.

Replace the contents of GameViewController.swift with the following:

import UIKit
import SceneKit
 
class GameViewController: UIViewController {
 
  override func viewDidLoad() {
    super.viewDidLoad()
  }
 
  override func shouldAutorotate() -> Bool {
    return true
  }
 
  override func prefersStatusBarHidden() -> Bool {
    return true
  }
}

The old code generated the spaceship; you’ve replaced that code with an empty slate. shouldAutorotate() handles device rotation and and prefersStatusBarHidden() hides the status bar.

Setting up Scene Kit

Earlier, you learned how Scene Kit uses the scene graph to display content on the screen. The SCNScene class represents a scene; you display the scene onscreen inside an instance of SCNView. Your next task is to set up a scene and its corresponding view in your project.

Setting up your Project’s View

Add the following property to GameViewController.swift, just above viewDidLoad():

var scnView: SCNView!

Here you declare a property for the SCNView that renders the content of the SCNScene on the display.

Next, add the following function just below prefersStatusBarHidden():

func setupView() {
  scnView = self.view as! SCNView
}

Here, you cast self.view to a SCNView and store it in the scnView property so that you don’t have to re-cast it ever time you need to reference the view. Note that the view is already configured as an SCNView in Main.storyboard.

Note: SCNView is a subclass of NSView in OS X, and a subclass of UIView in iOS. So whether you’re working with OS X or iOS, the same SCNView provides a view specifically for Scene Kit content.

Setting up your Project’s Scene

It’s time to set up your scene. Add the following property to GameViewController.swift, just below the scnView property:

var scnScene: SCNScene!

Here you declare a property for the SCNScene in your game. You will add components like lights, camera, geometry, or particle emitters as children of this scene.

Now add the following function below setupView():

func setupScene() {
  scnScene = SCNScene()
  scnView.scene = scnScene
}

This code creates a new blank instance of SCNScene and stores it in scnScene; it then sets this blank scene as the one for scnView to use.

Adding Finishing Touches

Now that you’ve created functions to set up instances of SCNView and SCNScene, you’ll need to call them from somewhere during the initialization step. A good place to do that is just after the view finishes loading.

Add the following lines to viewDidLoad(), just after the call to super:

setupView()
setupScene()

For the final finishing touch, you’ll add an app icon to your game. Download the tutorial resources and unzip the file; you’ll find app icons of various sizes in there for your use.

To set an image as the icon for your game, open the Assets.xcassets folder, select the AppIcon entry and drag each file from the Resources folder to the appropriate spot. Your AppIcon pane should look like the following when you’re done:

AddAppIcon

Build and run your project, and stand in awe of the black screen of opportunity! :]

BuildAndRun01

In all fairness, this might not seem very impressive at first, but you’ve come a long way already:

  • You’ve created a basic Scene Kit game project that uses built-in Scene Kit game template.
  • You also learned how to clean out the project by removing unnecessary folders such as art.scnassets.
  • Finally, you learned how to initialize an SCNView with a blank SCNScene.

Congratulations – you now have a blank slate to start with!

Where To Go From Here?

Here is the example code from this Scene Kit tutorial with Swift.

At this point, you should keep reading to the second part of this tutorial series, where you’ll get started making your game, learning about Scene Kit nodes along the way.

If you’d like to learn more, you should check out our book the 3D iOS Games by Tutorials. The book teaches you everything you need to know to make 3D iOS games, by making a series of mini-games like this one, including a games like Breakout, Marble Madness, and even Crossy Road.

In the meantime, if you have any questions or comments about this tutorial, please join the forum discussion below!

The post Scene Kit Tutorial with Swift Part 1: Getting Started appeared first on Ray Wenderlich.

Viewing all 4370 articles
Browse latest View live


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