Monday, 15 June 2015

Release news: Hungry Bunny & KeyChainItemCRUDKit

Not a technical post today, just a bit of news on the things I've been working on.

Firstly, my latest SpriteKit game written in Swift is now available on the App Store. It's called Hungry Bunny and is effectively an endless runner/skill test. It's free with ads.



Secondly, now that Hungry Bunny is complete I've returned to working on another project. This is nowhere near complete but I got to the point where I needed to securely store an OAuth2 token on iOS. I came across the Keychain API. However, the API for this was long winded and I only wanted to use it in a simple manner. Therefore I created a Swift framework to provide CRUD access to it along with a higher level interface where any type conforming to NSCoding and be saved, loaded & deleted.

This is available on github and also as my first ever CocoaPod. All the docs are in the README plus there's an example iOS program (Single View App) and the Unit Tests.

Saturday, 2 May 2015

Drawing into bitmaps and saving as a PNG in Swift on OS X

Not an in depth post today. For a small iOS Swift/SpriteKit game I'm writing for fun I wanted a very basic grass sprite that could be scrolled; to create a parallax effect. This amounts to a 800x400 bitmap which contains sequential isosceles triangles of 40 pixels with random heights (of up to 400 pixels) and coloured using a lawn green colour.

Initially I was creating an SKShapeNode and creating the triangles above but when scrolling the redrawing of these hurt performance, especially when running on the iOS Simulator hence the desire to use a sprite.

I had a go at creating these with Photoshop. Whilst switching to a sprite improved performance the look of the triangles drawn by hand wasn't as good as the randomly generated ones. Therefore I thought I'd generate the sprite.

It wasn't really practical to do this on iOS as the file was needed in Xcode so I thought I'd try experimenting with a command line OS X (Cocoa) program in Swift. A GUI would possibly be nice to preview the results (and re-generate if needed) and to select the save-to file location but this solution sufficed.

I'd not done any non-iOS Swift development and never generated PNGs so various amounts of Googling and StackOverflow-ing was needed. Whilst the results of these searches were very helpful I didn't come across anything showing a complete program to create a bitmap, draw into it and then save so the finished program is presented below. It's also available as a gist.


1:  import Cocoa  
2:    
3:  private func saveAsPNGWithName(fileName: String, bitMap: NSBitmapImageRep) -> Bool  
4:  {  
5:      let props: [NSObject:AnyObject] = [:]  
6:      let imageData = bitMap.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: props)  
7:        
8:      return imageData!.writeToFile(fileName, atomically: false)  
9:  }  
10:    
11:  private func drawGrassIntoBitmap(bitmap: NSBitmapImageRep)  
12:  {  
13:      var ctx = NSGraphicsContext(bitmapImageRep: bitmap)  
14:        
15:      NSGraphicsContext.setCurrentContext(ctx)  
16:        
17:      NSColor(red: 124 / 255, green: 252 / 255, blue: 0, alpha: 1.0).set()  
18:        
19:      let path = NSBezierPath()  
20:        
21:      path.moveToPoint(NSPoint(x: 0, y: 0))  
22:        
23:      for i in stride(from: 0, through: SIZE.width, by: 40)  
24:      {  
25:          path.lineToPoint(NSPoint(x: CGFloat(i + 20), y: CGFloat(arc4random_uniform(400))))  
26:          path.lineToPoint(NSPoint(x: i + 40, y: 0))  
27:      }  
28:        
29:      path.stroke()  
30:      path.fill()  
31:        
32:  }  
33:    
34:  let SIZE = CGSize(width: 800, height: 400)  
35:    
36:  if Process.arguments.count != 2  
37:  {  
38:      println("usage: grass <file>")  
39:      exit(1)  
40:  }  
41:    
42:  let grass = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(SIZE.width), pixelsHigh: Int(SIZE.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0)  
43:        
44:  drawGrassIntoBitmap(grass!)  
45:  saveAsPNGWithName(Process.arguments[1], grass!)  
46:    

Tuesday, 24 February 2015

When a Swift immutable collection isn't or is at least immutable-ish

Take the following code:

 struct Foo  
 {  
     var value: Int  
 }  
   
 let foo = [Foo(value: 1), Foo(value: 2)]  

By using 'let foo' an immutable array has been created. As such no members of this array can be replaced and nor can an element's contents be modified. As such both statements below result in compilation errors.

 foo[0] = Foo(value: 777) // error!  
 foo[0].value = 8 // error!  

If foo were declared var then both of the above statements would work.

This changes slightly when using reference types:

 class Bar  
 {  
     var value: Int = 0  
       
     init(value: Int)  
     {  
         self.value = value  
     }  
 }  
   
 let bar = [Bar(value: 1), Bar(value: 2)]  
   
 bar[0] = Foo(value: 777) // error!  
 bar[0].value = 8 // allowed  

The first case of trying to replace an element fails as before but modifying the instance referenced by that element is permitted. This is because the immutable collection holds a reference to the instance of Bar. Modifying the instance does not change the reference so the collection remains unchanged.

If you're making an effort to make your code as immutable (const) as possible (I'm from a C++ background so I endeavour to making everything as const I can) then this is a gotcha to lookout for.

The only way to make Bar properly const is to provide a private setter for the member, assuming it's defined in it's own source file (so this example doesn't work in a Plaground), i.e.

 class Baz  
 {  
     private(set) var value: Int = 0  
       
     init(value: Int)  
     {  
         self.value = value  
     }  
       
     func f()  
     {  
         value = 88;  
     }  
 }  

Which now prevents value being assigned too.

 let baz = [Baz(value: 1), Baz(value: 2)]  
 baz[0].value = 8 // error!  
   

Even if all the properties have private setters there might be methods on the reference type that modify the instance, such as f() above. Just having an immutable collection of reference types is not sufficient to stop these mutating the instances referred too. Invoking f() in the above collection will change the value to 88, i.e.

 println("\(baz[0].value)") // Gives 1  
 baz[0].f()  
 println("\(baz[0].value)") // Gives 88  
   

This differs to C++ where if a collection is const or is returned as a const reference (from a method) than not only is the container immutable but so are its contents. It would be good if Swift were to gain a mechanism that would mark the collection and its contents completely immutable other than having to use a value type.

Anyway, beware of making a collection of reference types immutable and assuming that both the collection and its contents cannot be modified!

Sunday, 22 February 2015

Book review: Swift Essentials

Disclaimer


I was asked to review: Swift Essentials by Alex Blewitt from Packt Publishing (I'd previously reviewed another book of theirs for the ACCU) and ideally publicise the review. In return I was given a free copy of the eBook and offered another free eBook of my choice upon publication of this review. However, no pressure was exerted and nor was any editorial control requested or given.

In short


It's a good book that provides a more than basic introduction to iOS development using Swift. My major criticism is the title, it does not do the book justice. The sub-title 'Get up and running lightning fast with this practical guide to building applications with Swift' is a far better description. This book is ideal if you're already able to program but would like to learn about iOS development with Swift rather than with Objective-C. It's more about learning iOS app development with Swift rather than about Swift.

In long


The offer to review this book came at good time for me. I'd read quite a lot of the Swift Programming Language book, read many blog articles, attended most of the Swift London meet ups (which incidentally gets a mention in the resource section of the book; so I may have inadvertently met the author) and published my first iOS App written entirely in Swift, a game called Boingy Splat. Therefore I was interested to see what someone else made of the language itself, working with it to create iOS apps and importantly to see parts and techniques I'd missed.

The books takes you from doing mainly pure Swift using REPL on the command line and then introducing and using Playgrounds to implementing a full app, albeit without persisting any data. Smaller apps demonstrating features that will be used in the final app are created along the way. These are small and snappy and allow something concrete to be created along the way, quickly! There is a section on creating Playground packages and adding documentation that seems far from essential; interesting though.

Some of the first chapter introducing the fundamental types and constructs can get a bit dull if you've been there with other languages but it's information that needs presenting. Importantly as soon as possible the Swift idioms (iteration, containers, enums, let versus var etc.) are presented. This is the information that existing developers need.

The Playgrounds chapters introduces a little Cocoa Touch by the way of displaying images. Other than the choice of the author's face as the content (ironic rather than egomaniacal I hope :-)) it's good to be already manipulating the OS with Swift rather than just 'doing' Swift.

From chapter 3 onwards (there are 7 in total) the focus switches to creating apps. The most important concepts (that will allow you to search for and understand more detailed documentation and blogs) are introduced, i.e. Table Views, Master-Detail, Storyboards (and creating purely programmatic views), Custom Views, MVC architecture and accessing remote data. No time is spent on app signing etc. which is an understandable omission but a mention and a reference could prove useful for those very new to iOS development.

The later chapters tend to introduce a new iOS features and new Swift feature making use of one with the other. Even Unit Testing gets a mention when introducing classes and using mocking as example of sub-classing. Likewise full and practical use of Swift's enums and extension methods are given in the remote data chapter.

I was pleased to see Storyboards getting central billing for creating UIs as this is now more or less de rigueur and was always my issue with the Big Nerd Ranch book. The use of Segues is also covered along with how to create the UI using Interface Builder. In this chapter and the rest of the book a fair amount of time is spent showing how to pass data from from View to another. It's a shame the Singleton anti-pattern is presented as a way to share data in the final program especially given the coupling this causes which makes Unit Testing as advocated earlier in the book hard to accomplish.

As this is a new book it was good to see it tackle Auto Layout and not just from the Interface Builder perspective but go so far to explain and use the Visual Format Language. It's quite a feat to present this succinctly and not just cop out with a reference to the official documentation. It's this information that takes a somewhat scary area of iOS development and removes the fear.

The remote data chapter is good in that talks about synchronous versus asynchronous calls and makes use of Swift Closures for the callbacks. It covers useful details such as having to update the UI on the main thread versus performing work on others and shows the mechanisms to achieve this. A small library of useful methods that can be used outside of the book is created in the process. Again, this isn't super detailed information but it's setting new iOS developers on the right course allowing common areas of pain and confusion to be avoided.

Other than title the I have only a couple of criticisms. Firstly, I kept finding references to things either just before they were presented or to unhighlighted aspects of the code. This suggested that in order to keep the size of the book down that various pages had been chopped but less than perfect re-editing had occurred. I was able to reconcile all of these but it meant spending time flicking back through pages. Secondly, in a similar vein whilst the book contains screenshots there are sections where some intermediate screenshots or those of the final effect would aid the description. It's arguable as to whether the persistence of data is an 'essential'. I think it would have been worth taking the page count to 250 (from the current 228) to cover basic persistence; 2nd edition?

Formatting


I read the eBook on iPad mini 2 using the Kindle reader app (mobi format); I haven't seen the paper version.

For technical eBooks, especially to be read on anything smaller than a full size tablet means the formatting, especially of the code is very important. The text is laid out well and most of the code is split-up so the differences between text and code highlight the other which works well. There were a few times when I needed to switch to landscape mode to make the code more readable.

Towards the end where a full program in larger sections is presented it breaks down as there is little text on the same page. Different colours would have been useful for the comments and given the use of inline lambdas (for asynchronous calls) then some other formatting or again another colour would have helped separate these from the code consuming them; though I did notice some use of bold. The use of ANSI rather K&R style braces (though this seems preferred by Apple and is more compact) may have help readability.

Conclusion


When Swift was first released (June '14) a lot of people thought that learning Swift would make then iOS developers whereas the real challenge (other than learning how to program) is to learn how to program against iOS. At that time learning just Swift by itself as a first language had no real benefit especially as all the books and blog articles used Objective-C plus the Cocoa Touch APIs were still rather Swift unfriendly.

Whilst knowing Objective-C is probably essential for a full-time iOS developer today and a basic knowledge will be useful for a long time to come, 8 months down the line learning iOS development just with Swift is extremely viable. This book will allow you to do this. It's not as comprehensive at the de facto book for learning iOS development: Big Nerd Ranch's iOS Programming but it is more than sufficient, uses the latest language and covers features introduced with Xcode 6, e.g. Auto Layout and demonstrates app development along the lines of how Apple sees it, by using Storyboards and Auto Layout. It's also significantly shorter!

Whilst it doesn't cover everything and what it does cover doesn't go into great detail it introduces and uses most of the key concepts of both Swift and iOS. To write an app you'll still need to read and refer to the official documentation and read blogs etc. but after reading this book there will not be much that is alien to you.

I'd recommend this book if you can already program and would like to learn how to develop for iOS. If you already know iOS but would like to learn Swift with familiar examples and see how to access the Cocoa APIs using Swift then this is also a good book. Even if you can't program and aspire to iOS development then this is a book that you could pick up and get a long with pretty soon after you'd got to grips with the basics of programming.

I think it is possible for this to become the 'go to' book for starting iOS development.

Wednesday, 28 January 2015

Optional chaining with dictionaries (in Swift)

Whilst learning Swift and SpriteKit I came across an issue with the documentation for SKNode.userData. In an early XCode beta it was specified as an implicitly unwrapped optional whereas now it is clearly an optional.

Therefore the code I originally used to access values was:

var node = SKNode()
...
if let userData = node.userData
{
    if let value = userData["key']
      // do something with value
}

Once I discovered optional chaining I was able to shorten this to:

var node = SKNode()
...
if let value = userData?["key"]
{
  // do something with value
}

I.e. Use optional chaining to check for existence of userData

This is not something I've seen written about before. Optional chaining  of subscripts is mentioned in The Swift Programming Language book but this only appears in reference to providing a custom subscript operator for a class as opposed to using it with stock types and a brief mention in connection with Dictionaries when the key is not present is also made, e.g.

var dict = ["foo": "hello"]
dict["bar"]? = "world"

The latter is interesting as without the '?' then "world" will be inserted along with the creation of the "bar" key whereas using optional chaining the key must already exist.

Both forms can be combined, e.g.

var dict : [String : String]?
dict?["bar"]?= "world"

which will only insert world if the key "bar" exists and dict exists.

The use of optional chaining with subscript types can lead, like lots of other uses of optional chaining to more readable & succinct code, this is just another example.

Sunday, 29 June 2014

Resolving strong references between Swift and Objective-C classes - Using unowned and weak references from Swift to Objective-C classes

My Swift and SpriteKit exploration continues. At the moment I'm writing the collision handling code.

Rather than derive game objects from SKSpriteNode with each derived class containing the code for handling collisions with the other types of game objects I'm following something akin to a Component-Entity model.

I have per-game-object handler classes of which an instance of each is stored in the actual SKSpriteNode's userData dictionary. In turn each handler instance has a reference to the SKSpriteNode that references it. Given ARC is used this is a classical strong-reference chain which will prevent memory from being freed. The usual solution to this in Objective-C is to have one of the references be weak. In Swift there are two types of weak references: weak which is the same as in Objective-C and unowned (which I think is new). The difference is that an unowned reference can never be nil, i.e. it's optional whether a weak pointer reference an object but an unowned pointer must always reference something. As such the member variable is always defined using let and must be initialized, i.e. an init method is required.

The following code shows how I was intending to implement this. There is the strong reference from node.UserData to PhysicsActions and then the unowned reference back again from PhysicsActions.

class PhysicsActions
{
  unowned let node : SKSpriteNode

  init(associatedNode : SKSpriteNode)
  {
    // Store really weak (unowned) reference
    self.node = associatedNode
  }

  func onContact(other : PhysicsActions)
  {
     // Do stuff with node

  }
}

class func makeNode(imageNamed name: String) -> SKSpriteNode
{
  let node = SKSpriteNode(imageNamed: name)
  node.userData = NSMutableDictionary()
  // Store strong reference
  node.userData["action"] = makeActionFn(node)
  return node

}

However, when I went to use this code it crashed within the onContact method when it attempted to use the node. Changing this the reference type from unowned to weak fixed this, e.g.

weak let node : SKSpriteNode?

This verified that the rest of the code was ok so this seemed to look like another Swift/Objective-C interoperability issue. Firstly, I made a pure Swift example which is a simplified version from the The Swift Programming Language book.

class Foo
{
  var bar : Bar?

  func addBar(bar: Bar)
  {
    self.bar = bar
  }
}

class Bar
{
  unowned let foo : Foo
  init(foo : Foo)
  {
    self.foo = foo
  }

  func f()
  {
    println("foo:\(foo)")
  }
}

var foo : Foo? = Foo()
var bar = Bar(foo: foo!)
foo!.รง(bar)

bar.f()

Which works and results in:

foo:C14XXXUnownedTest3Foo (has 1 child)

Ok, not a fundamental problem but let's try having an unowned reference to an Objective-C class which is just like the real case as that's what SKSpriteNode is.

Foo2.h

@interface Foo2 : NSObject
@end

Foo2.m

@implementation Foo2

-(id)init
{
  return [super init];
}

@end

main.swift

class Bar2
{
  unowned let foo2 : Foo2
  init(foo2 : Foo2)
  {
    self.foo2 = foo2
  }

  func f()
  {
    println("foo2:\(foo2)")
  }
}

var foo2 = Foo2()
var bar2 = Bar2(foo2: foo2)
bar2.f()

Which when foo2.f() is invoked results in:

libswift_stdlib_core.dylib`_swift_abortRetainUnowned:
0x100142420:  pushq  %rbp
0x100142421:  movq   %rsp, %rbp
0x100142424:  leaq   0x17597(%rip), %rax       ; "attempted to retain deallocated object"
0x10014242b:  movq   %rax, 0x348be(%rip)       ; gCRAnnotations + 8
0x100142432:  int3   
0x100142433:  nopw   %cs:(%rax,%rax)

Again, changing unowned let foo2 : Foo2 to weak var foo2 : Foo2? works. 

I can't explain what the actual problem is but it looks like the enhanced weak reference support (unowned) only works with pure Swift classes. If you have cyclic references to Objective-C classes from Swift then don't use unowned. In fact writing the previous sentence led me to try the following:

let orig = Foo2()
unowned let other = orig
println("other:\(other)")
println("orig:\(orig)")

No cyclic references, just an ordinary reference counted instance of Foo2 (the Objective-C class) which is then assigned to an unowned reference. The final call to println will keep the instance around until the end. This crashes as per the previous example when the other variable is accessed. Changing the type assigned to orig from Foo2 (Objective-C) to Foo (Swift) make it work.

Therefore it seems unowned should not be used to refer to Objective-C classes, just Swift classes.



Tuesday, 24 June 2014

Beware: Despite the docs SKNode userData is optional

In the Swift documentation for SKNode the userData member (a dictionary) is defined as follows:

userData

A dictionary containing arbitrary data.

Declaration

SWIFT
var userData: NSMutableDictionary!

OBJECTIVE-C

@property(nonatomic, retain) NSMutableDictionary *userData

However, in Objective-C the userData member is initially nil. Given that this is the same class then it should also be in Swift and using it, e.g.

let node = SKSpriteNode(imageNamed: name)
node.userData["action"] = Action() // custom class

causes a crash:

fatal error: Can't unwrap Optional.None

This is because the it is in fact nil despite the '!' following the Swift definition. This must be a documentation bug. The correct code is:

let node = SKSpriteNode(imageNamed: name)
node.userData = NSMutableDictionary()
node.userData["action"] = Action() // custom class