ARKit on iOS 11

ARKit is the “largest AR platform in the world” according to Apple’s latest keynote address from WWDC 2017. So what can it do? Well, as we saw in the demos, ARKit enabled features for surface tracking, depth perception, and integrated with existing libraries from the game development world. Note: If you’re here to learn how to make ARKit apps, I’ve got a detailed tutorial over here: ARKit Tutorial.

Most significantly, Apple showed that both the Unreal and Unity game engines will integrate with ARKit for support for Pokemon Go-esque apps. Multiple objects can interact with each other casting shadows with each other, and even having physics reactions. Some say this development means Apple will soon be releasing a Hololens style device. I personally think they just want to enable better experiences like what Snapchat offers today.

On the other hand, ARKit will also give developers of photo editing apps a better way to dive deep in to the contents of user’s photos in orer to enable new and improved photo editing experiences. Deep learning powered photo editing will be sure to make mobile photo (and video) editing a much better experience.

ARKit has support for:

Fast, stable motion tracking
Plane estimation with basic boundaries
Ambient lighting estimation
Scale estimation
Support for Unity, Unreal, SceneKit
Xcode app templates

Did this tutorial help you?

Support my Patreon

Your support on Patreon allows me to make better tutorials more often.

Subscribe via RSS

Objective-C Pointers and Swift 2: A Simple Guide

This post written on August 23, 2015 to be compatible with Xcode 7 Beta and Swift 2

Objective-C Pointers and Swift

Reading C pointers from Swift

Let’s say I have a C Int object as a Swift pointer.

For example this Objective-C method would return an int pointer, or (int *) in C terminology:


@interface PointerBridge : NSObject {
    int count;
}
- (int *) getCountPtr;
@end
 
@implementation PointerBridge
- (instancetype) init {
    self = [super init];
    if(self) {
        count = 23;
    }
    return self;
}
- (int *) getCountPtr {
    return &count;
}
@end

If you’re unfamiliar with Obj-C or C syntax, the above basically just declares a class called PointerBridge, and it has a single method called getCountPtr, which returns the memory address of an int whose value is 23. The Int is just a variable on the instance called count, which gets set to 23 in the constructor, init.

I put this in an Objective-C h-file and import it in to my bridging header in order to expose it to Swift. Then in Swift I create the PointerBridge class as a new instance called bridge, and get the result of the getCountPtr() method…


let bridge = PointerBridge()
let theInt = bridge.getCountPtr()
print(theInt)
print(theInt.memory)

Examine the type of theInt by holding the Option key and clicking the variable name in Xcode, and you’ll find it’s Swift type is a UnsafeMutablePointer<Int32>. This is a pointer to an Int, which is not the same thing as being an Int… It just points to it.

If we run this small program and allow this Swift to execute, we’ll see theInt printed to the console as a memory address, something like 0x00007f8bdb508ef8. Then, we’ll see the value 23 printed from the memory member. Accessing memory on a pointer generally returns the underlying object, in this case just the original 32-bit int (brought in to Swift as an Int32)

Now consider our Objective-C class also allows us to set the value of count.


@interface PointerBridge : NSObject {
    int count;
}
- (int *) getCountPtr;
- (void) setCount:(int)newCount;
@end
 
@implementation PointerBridge
- (instancetype) init {
    self = [super init];
    if(self) {
        count = 23;
    }
    return self;
}
- (int *) getCountPtr {
    return &count;
}
- (void) setCount:(int)newCount {
    count = newCount;
}
@end

Now, we could modify the value for count by calling setCount(). Since theInt is a pointer, updating the count value using setCount should also update theInt.memory. The memory address won’t change after all, just the value.

In other words, the following should log to the console the number 23, and then the number 1000.


let bridge = PointerBridge()
let theInt = bridge.getCountPtr()
print(theInt.memory) // 23
bridge.setCount(1000)
print(theInt.memory) // 1000

A shortcut you might want to take, to avoid writing .memory all the time, is to assign .memory to a variable:


let bridge = PointerBridge()
let theInt = bridge.getCountPtr()
let countVal = theInt.memory
print(countVal) // 23

As before, 23 is printed to the console. However, if I do the same thing we did before, and modify the underlying count value by calling setCount(), we see a problem crop up:


let bridge = PointerBridge()
let theInt = bridge.getCountPtr()
let countVal = theInt.memory
print(countVal) // 23
 
bridge.setCount(1000)
print(countVal) // 23

What’s happening here is that countVal is being assigned by value. At the time of assignment the value is 23, so countVal actually has it’s own memory address where it stores 23 permanently, thus losing it’s pointer nature. countVal is just a regular Int32 now.

Creating C pointers from Swift Objects

What if we wanted to do the inverse of what we did above? Instead of setting the value of count with an Int, what if we needed to pass in a pointer?

So in the Objective-C let’s say there was a method like this:


- (void) setCountPtr:(int *)newCountPtr {
    count = *newCountPtr;
}

This method is pretty contrived, and just ends up re-assigning the value of the newCountPtr, but in your Swift development you will face real-world scenarios of needing to pass in pointers. This one is contrived simply to demonstrate how to create the pointer type from Swift, and pass it in.

You might think you could simply pass in an Int value, with a reference operator like &. This is how you might do this same thing in C. Or for example in Objective-C you would write this:


int mcount = 500;
[self setCountPtr:&mcount];

Which would update the count value to be 500 successfully. However in Swift, you may see just from auto-complete that it wants something a little more complicated (and verbose). It’s looking for a newCountPtr of type UnsafeMutablePointer<Int32>.

I know this type is a mouthful, and it looks really complicated. However, it’s actually fairly simple, especially if you know pointers from Obj-C. In order to create an object with type UnsafeMutablePointer<Int32>, we just call the constructor and for it’s only argument we pass in the size of the pointer in units of the number of objects.


let bridge = PointerBridge()
let theInt = bridge.getCountPtr()
print(theInt.memory) // 23
 
let newIntPtr = UnsafeMutablePointer<Int32>.alloc(1)
newIntPtr.memory = 100
bridge.setCountPtr(newIntPtr)
 
print(theInt.memory) // 100

The only argument to the UnsafeMutablePointer<Int32> constructor is how many objects worth of space will be allocated, so we can just pass in 1 since we only need 1 Int32 object. Then, simply inverting what we did before with the memory property, we can assign a value to our newly created pointer. Finally, we can simply pass in the newIntPtr to the setCountrPtr method. Printing out the value of the original theInt pointer, we see the value has indeed been updated to 100.

Conclusion

The UnsafeMutablePointer<T> type, and it’s sibling UnsafePointer<T> are basically just abstractions of C pointers. If it helps to wrap your head around them, think of them sort of like Swift Optionals, in that they do not directly equate to a certain value, but instead act as an abstraction layer on top of a contained variable. The type is generic, and allows for other types to be used than just Int32. For example if you needed to work with a Float object you might need an UnsafeMutablePointer<Float>.

The important thing to remember is that you do not cast from an Int to an UnsafeMutablePointer<Int>, because a pointer is simply not the same as an Int value. So instead, be prepared to create a new object, calling it’s constructor UnsafeMutablePointer<Int>(count: Int).

We’ll follow-up this post with a deeper dive in to the details of function pointers, and how to take advantage of these features to work with legacy C and Objective-C APIs. Make sure to sign up for our newsletter so you don’t miss it!

Subscribe For Free Now »

Did this tutorial help you?

Support my Patreon

Your support on Patreon allows me to make better tutorials more often.

Subscribe via RSS

WWDC 2015 Developer Highlights

Today Apple announced watchOS, delivering a new native SDK for developers at WWDC 2015, a new version of Mac OS X known as OS X El Capitan.

Mac OS X El Capitan

Shaking the mouse makes the cursor appear larger to make it easier to find.

Safari now includes “pinning” of tabs, which leaves permanent icons on the top of the tab view in the browser, and it also seems to precut so it loads instantly.

Spotlight is using natural language processing to greatly improve search functionality. For example, “mail i ignored from phil” to see emails not replied to.

Mail now supports multiple tabs for composing emails, and allows drag and drop between emails.

Mission control is now much simpler, supports left/right docking of windows similar to Windows 7.

Generally seems to have improved drag and drop support across the board.

Metal has now been ported to Mac OS, and has been implemented in the Unreal Engine.

iOS 9

Siri has greatly improved NLP.

Siri is now also proactive, for example if you listen to music while running, the lock screen can offer up your music. Then when you hop in to your car (which it can detect), it will switch to that audiobook you’ve been listening to.

Siri Suggestions can recommend news, nearby places, and people. iOS 9 also remembers when you use certain apps, and will recommend then on the lock screen in the same way Handoff does.

Siri is now context sensitive, “remind me about *this* later today” will create a reminder based on what is currently on-screen.

Search is greatly improved, integrating with YouTube, iTunes, and it provides an API for developers.

These features are collectively referred to by Apple as “intelligence”. It does not undermine your privacy. Everything is done on-device.

Notes is greatly improved, and added support for all types of interactive content.

Maps also greatly improved, transit and navigation integrate with Siri.

A new app called “News” has been added to iOS 9, a Flipboard-Like app directly from Apple. News supports recommendations based on your tastes, and provides multimedia support including video.

iPad

iPad now support a PIP-style multi-tasking, slipovers bringing in apps from the side and enter split view for true multi-taksing.

The Search API

iOS 9 SDK will provide an API for search, with support for deep links within apps.

iOS 9 SDK provides split view APIs, using just auto layout. Twitter was able to implement within a few minutes.

Swift 2

Swift will now be OPEN SOURCE later in 2015. With standard library support for Linux, Mac OS, and iOS.

Did this tutorial help you?

Support my Patreon

Your support on Patreon allows me to make better tutorials more often.

Subscribe via RSS

Fun with CAShapeLayer

CAShapeLayer is a specialized subclass of CALayer that draws itself using the shape you define via the path property. path is an instance of CGPath. We could leverage the convenient UIBezierPath APIs to create a path, and then retrieve the CGPath from it. Besides all the animatable properties inherited from CALayer, there are other animatable properties that let you control attributes such as fill color, stroke color, line thickness, etc. In this tutorial, I will illustrate some visual effects using these properties.


Looking for something more in-depth? Try my book & video courses
Get The Swift Book
Learn About My Book & Video Packages »

Let’s Get Started!

First, you need to download the starter project from here.

Rounded Corners

There are different ways to draw rounded rectangles.

Go to RoundedCornersViewController class, add the following codes at the end of viewDidAppear method.

// 1
rectShape1.backgroundColor = UIColor.redColor().CGColor
rectShape1.cornerRadius = 20
// 2
rectShape2.fillColor = UIColor.greenColor().CGColor
rectShape2.path = UIBezierPath(roundedRect: rectShape2.bounds, cornerRadius: 20).CGPath
// 3
rectShape3.fillColor = UIColor.blueColor().CGColor
rectShape3.path = UIBezierPath(roundedRect: rectShape3.bounds, byRoundingCorners: .BottomLeft | .TopRight, cornerRadii: CGSize(width: 20, height: 20)).CGPath

1. The first way to draw a rounded rectangle is to change a layer’s cornerRadius property. This applies to all CALayerS.
2. We could also use path to draw a rounded rectangle. Assign a rounded rectangle path via this convenient method on UIBezierPath. By doing this, we have to use fillColor instead of backgroundColor. Because backgroundColor is color of the layer’s background, while fillColor is the color used to fill the shape’s path.
3. Using path, we are not limited to round all corners. We could specify which corner we want to round. In this example, I only change bottom left and top right corners.

Run and select Rounded Corners cell.

Path Animation

path is also an animatable property. We could achieve the basic Material-Design-feel effect by animating it.

Go to PathViewController class, add the following codes at the end of viewDidAppear method.

// fill with yellow
rectShape.fillColor = UIColor.yellowColor().CGColor

// 1
// begin with a circle with a 50 points radius
let startShape = UIBezierPath(roundedRect: bounds, cornerRadius: 50).CGPath
// animation end with a large circle with 500 points radius
let endShape = UIBezierPath(roundedRect: CGRect(x: -450, y: -450, width: 1000, height: 1000), cornerRadius: 500).CGPath

// set initial shape
rectShape.path = startShape

// 2
// animate the `path`
let animation = CABasicAnimation(keyPath: "path")
animation.toValue = endShape
animation.duration = 1 // duration is 1 sec
// 3
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) // animation curve is Ease Out
animation.fillMode = kCAFillModeBoth // keep to value after finishing
animation.removedOnCompletion = false // don't remove after finishing
// 4
rectShape.addAnimation(animation, forKey: animation.keyPath)

1. Calculate begin and end shapes for the animation. Then assign the startShape to path.
2. Use CABasicAnimation to animate path. Destination value for path is the end shape we defined before. Set it to toValue. Then set the animation duration to 1 second.
3. Set the animation curve to ease out, making it look more natural. With removedOnCompletion set to false, fillMode to kCAFillModeBoth, when the animation finishes, rectShape will remain the end shape.
4. Add the animation to the layer.

Run and select path Animation cell. See the animation:

View Movie

Line Width Animation

lineWidth defines the stroke line width of the shape’s path, and it’s also animatable. There are some cool effects we could make via lineWidth.

Go to LineWidthViewController class, add the following codes at the end of viewDidAppear method.

// setup
let rect = CGRect(x: 0, y: 0, width: view.bounds.width, height: 1)
rectShape.bounds = rect
rectShape.position = view.center
rectShape.path = UIBezierPath(rect:rect).CGPath

// 1
rectShape.lineWidth = 10
rectShape.strokeColor = UIColor.blueColor().CGColor

// animate
let animation = CABasicAnimation(keyPath: "lineWidth")
// 2
animation.toValue = 1000
animation.duration = 1 // duration is 1 sec
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) // animation curve is Ease Out
animation.fillMode = kCAFillModeBoth // keep to value after finishing
animation.removedOnCompletion = false // don't remove after finishing
rectShape.addAnimation(animation, forKey: animation.keyPath)

1. Give an initial line width of 10 points. To set the line color, we use strokeColor.
2. Similar to path animation, animate line width to 1000.

Run and select lineWidth Animation cell. See the animation:

Stroke Animation

strokeStart and strokeEnd defines the relative location at which to begin stroking the path, ranging from 0 to 1. Many cool activity indicator can be made by using them. Here is a simple example that show you how to animate these properties.

Go to StrokeViewController class, add the following codes at the end of viewDidAppear method.

// 1
rectShape.path = UIBezierPath(ovalInRect: rectShape.bounds).CGPath

rectShape.lineWidth = 4.0
rectShape.strokeColor = UIColor.lightGrayColor().CGColor
rectShape.fillColor = UIColor.clearColor().CGColor

// 2
rectShape.strokeStart = 0
rectShape.strokeEnd = 0.5

// 3
let start = CABasicAnimation(keyPath: "strokeStart")
start.toValue = 0.7
let end = CABasicAnimation(keyPath: "strokeEnd")
end.toValue = 1

// 4
let group = CAAnimationGroup()
group.animations = [start, end]
group.duration = 1.5
group.autoreverses = true
group.repeatCount = HUGE // repeat forver
rectShape.addAnimation(group, forKey: nil)

1. Here is another way to draw a circle using another UIBezierPath’s convenient initializer.
2. Set the initial values for strokeStart and strokeEnd.
3. Create animations like before.
4. Group two animation together. Because we want to both animations to happen simultaneously. The duration is 1.5 seconds. It will auto reverse the animations upon finishing. And it will repeat forever.

Run and select Stroke Animation cell. See the animation:

Conclusions

You could find the complete project on Github. If you have further questions, you can leave a comment or ask me on Twitter.

Did this tutorial help you?

Support my Patreon

Your support on Patreon allows me to make better tutorials more often.

Subscribe via RSS

Swift 1.2 and Xcode 6 Beta 2 – The best update yet

The big news in the Swift community is the release of Swift 1.2, featuring some awesome features. Apple wrote about that a bit here, this was before they released Xcode 6.3 Beta 2, which came out today. But it contains most of the major language changes.

Xcode 6.3 Beta 2

First of all, Xcode itself has changed to allow for more easy to use playgrounds. In particular Apple has added rich text comments, in addition to showing results inline rather than in a separate timeline view. Swift performance was also further improve, and an additional method called zip was introduced for merging Swift sequences together.

zip()

Zip is a method that comes straight out of Haskell which accepts multiple sequences of data, and returns a single tuple “zipping” the two data sets together. For example

let a = [1,2,3]
let b = ["a","b","c"]
let zipped = zip(a, b)

Here the value of zipped would become two sequences in a tuple with types [Int] and [String]. Casting this to an Array makes the significance of this a little more clear:

println(Array(zipped))

[(1, a), (2, b), (3, c)].
As you can see the two sequences are simply “zipped” together. This does beg the question though, what if the sequences are of differing lengths?
For example…

let a = [1,2,3]
let b = ["a","b"]
let zipped = zip(a,b)

In this case, the zipping process will use the shortest sequence’s length as the number of elements to zip, and simply discard the trailing elements on the longer sequence. Giving the output, [(1, a), (2, b)]

This is particularly useful when working with what are effectively infinite sequences. You can limit the list by zipping with a finite sequence:

    let squares = Array(map(1..<10) { $0 * $0 })
    let names = ["one", "two", "three"]
    
    let squareList = zip(names, squares)
    
    println(Array(squareList))

Results in:
[(one, 1), (two, 4), (three, 9)]

So, even though the squares sequence can go on forever, it's made in to a finite list due to the fact that names has only 3 elements.

Goodbye pyramid of doom!

The optional binding sometimes leads to messy code like this:

if let first = user.first {
  if let last = user.last {
    return "\(first) \(last)"
  }
}

But with 1.2, these series of if let statements can be collapsed down to just a comma separated list of optional values, and only a single set of curly braces. The above code will behave exactly the same as this:

if let first = user.first, last = user.last {
  return "\(first) \(last)"
}

Sometimes these chains upon chains of optional binding statements can get out of hand, so this is a very welcome feature. As an additional bonus in Xcode 6.3 Beta 2, we can now also add a single optional binding let clause. For example:

if age > 17 && profile.public,
  let first = user.first,
  last = user.last {
    return "\(first) \(last)"
}

This code will not only perform the optional binding in a more concise way with the variables first and last, but it will only do so if the user is of age and has a public profile available, which are assumed to be boolean values in this example. Contrast that with how we wrote this in older versions:

if (age > 17 && profile.public) {
  if let first = user.first {
    if let last = user.last {
      return "\(first) \(last)"
    }
  }
}

The as! keyword was added

When casting from one type to the other, it's possible that the cast could fail. Previously this was handled with the case of an optional using the as? operator. Consider the scenario below

func bio(name: String, location: String) -> String {
  ...
}

var name: AnyObject
name = "Jameson"
var location = "Austin, TX"
let nameStr = name as String
bio(nameStr, location)

Here we are calling a function that requires a String, but we have name typed as an AnyObject object. Before Swift 1.2 this code would be accepted, but this could actually crash your application if the cast fails. In this case it would never fail, so we can safely do this cast, but the syntax shown above does not clearly demonstrate that this cast is actually dangerous. If name gets changed to something that is not castable to a String later, this code would cause the app to crash. In order to more clearly communicate this, the as operator must now become as! if the cast could possibly fail. So the above would now become this:

func bio(name: String, location: String) -> String {
  ...
}

var name: AnyObject
name = "Jameson"
var location = "Austin, TX"
let nameStr = name as! String
bio(nameStr, location)

This helps drive home an important message: If you are using an exclamation mark (!), then you may be setting up a situation where the app could crash due to a failed cast, or null value. As a general rule, you should just never use forced casts unless you absolutely have to (or if you're writing code that won't go in to production)

Keep in mind the as? keyword is unchanged, and in general you should prefer using it in addition to an optional binding for this type of scenario, as this is much safer, e.g.

func bio(name: String, location: String) -> String {
  ...
}

var name: AnyObject
name = "Jameson"
var location = "Austin, TX"
if let nameStr = name as? String {
  bio(nameStr, location)
}

Xcode and Compiler Improvements
This is probably the biggest one for me. The compiler is faster due to incremental builds, and Xcode doesn't crash all the time due to some stability improvements. This alone makes the beta work the download and I highly recommend getting a copy on iOS Dev Center.

Want to learn more about Swift 1.2? Try out some of my free tutorials. My Core Data tutorial was updated recently for 1.2, which I would recommend to anyone interested in working on real iOS Apps.

Did this tutorial help you?

Support my Patreon

Your support on Patreon allows me to make better tutorials more often.

Subscribe via RSS

Access Control In Swift

Updated December 21 for Xcode 6.1.1

The Swift feature of Access Control is really important from a software architecture perspective, because it allows us to properly implement encapsulation. Without the ability to hide members and methods of classes, it’s very easy to accidentally (or not) reach in to classes and mess with internals that were not designed to be directly modified.

Swift offers three levels of access control: public, private, and internal.

public makes the entities visible anywhere within the module, or from other modules (as long as the module is imported)
internal makes the entities visible only within the same module. This is the default behavior in Swift.
private makes the entities visible only within the same source file.

To demonstrate Swift’s new access controls, let’s build a small math class for Swift. For now, it’ll be really simple. It’s a class that has two properties of type Double, and has a single computed property named sum. If you want to follow along, just create a single-view template project and add this in to an otherwise empty swift file called Math.swift

import Foundation

class QMath {
    
    var num1: Double?
    var num2: Double?
    
    var sum: Double {
        return num1! + num2!
    }
    
    init(_ num1: Double, _ num2: Double) {
        self.num1 = num1
        self.num2 = num2
    }
    
}

The class QMath has a constructor that takes two parameters, num1 and num2 of type Double. If you haven’t seen the underscores before, those are the external parameter names, which we’ve set to not be specified by using the underscore. If we instantiate a QMath instance in another class we can get the sum property and confirm it works as expected.

If you’re following along, you insert this in to your applicationdidFinishLaunchingWithOptions: method inside of AppDelegate.swift

var m = QMath(4, 50)
println(m.sum)
54.0

You’ll notice that in our sum getter, we implicitly unwrap num1 and num2 using the exclamation mark (!). Although they’re both optionals, we can make this assumption if we know the init(,) method we’ve provided is called, because the arguments to that method are not optional and will definitely be set upon initialization.

Except one minor problem:
We could actually set either of those values to be nil.

var m = QMath(4, 50)
m.num1 = nil
println(m.sum)

This code compiles just fine, num1 is Optional and can be set to nil, not an issue. However, calling the sum getter now implicitly unwraps a nil optional. If you run this code you’ll see the following error:

fatal error: unexpectedly found nil while unwrapping an Optional value

We could simply set the num1 and num2 properties to not be optional, which would require we have a default value such as 0. But, an better approach that allows us to avoid the unnecessary initial value is to simply disallow modifications to these internal variables. We want this class to be a black box, where num1 and num2 can’t directly be modified.

So, to solve our above mentioned issue, we can make the two number properties private.

private var num1: Double?
private var num2: Double?

Attempting to build the app again now produces an error on the line we used to set num1 to nil.

m.num1 = nil
'QMath' does not have a member named 'num1'

Our external reference to the num1 property is no longer valid, it has no visibility to num1 and therefore this line of code is an error. There’s only one thing to do now, remove this line and start using the class as it was designed to be used! Mission accomplished!

If you want to dive deeper and tinker with Swift, it’s a good idea to read my post on Running Swift Scripts From The Command Line. When you’re ready to get serious make sure to also learn about my upcoming Swift eBook and video tutorial series.

Warning: Incoming opinion
Good software design principles suggest everything should be private by default, and entities should be exposed deliberately on an as-needed basis. This makes it easier to write more modular code and leads to cleaner programming interfaces. Disagree? Yell at me about it on Twitter.

Did this tutorial help you?

Support my Patreon

Your support on Patreon allows me to make better tutorials more often.

Subscribe via RSS