Wednesday, 23 December 2015

Git remote repos with OneDrive

I have various public git repositories on GitHub but I like to keep some source (usually my active App Store apps) private. Whilst it'd be nice to use GitHub private repositories, given my Apps are for fun and don't really make anything, don't require collaboration then the pricing is prohibitive.

However, I really like the idea of having an offsite copy of my repository. As it happens I have an Office 365 Subscription which comes with 1TB of OneDrive space. I use OneDrive on OSX to sync a bunch of folders. I could use a synchronised OneDrive for my work directory but I don't want OneDrive synchronising all the temporary build files etc every time I build.

It turns out the ideal solution is to create a remote clone in a OneDrive synchronised folder. In fact I have a dedicated OneDrive folder called 'src' that contains clones of all of my git repos. Then, each time I commit to the local git repository and push OneDrive performs the synchronisation. If it happens that the code I'm working on is public then adding a public GitHub repo is a doddle.

Having created a local Git repo (though usually Xcode does this when starting a new project) it's easy to create the OneDrive clone:

  1. cd /Users/Pete/OneDrive/src
  2. git clone --bare file:////Users/Pete/Projects/<ProjectName>/.git <ProjectName>.git
As the remote clone is really just a backup come master that will never be working repository I create a bare clone and suffix the directory name with '.git'. I think this is a fairly common convention.

At this point the source repository is cloned but the source is now a remote of the new repository rather than than the other way round. This is easy to fix:

cd-ing into <ProjectName>.git (my example Project is Photone> and running git remotes gives:

~/OneDrive/src/Photone.git[23]git remote -v
origin file:////Users/Pete/Projects/PhotoneViewer/.git (fetch)
origin file:////Users/Pete/Projects/PhotoneViewer/.git (push)

than running:
  1. git remote remove origin
Removes the relationship between the new remote and the original source. To implement the desired reverse relationship:


  1. cd /Users/Pete/Projects<ProjectName>
  2. git remote add OneDrive file:////Users/Pete/OneDrive/src/<ProjectName>.git
I name my OneDrive remote repos 'OneDrive'. This helps if I have multiple remotes.

git remote (for my current project) now gives:


~/Projects/PhotoneViewer[49]git remote -v
OneDrive file://Users/Pete/OneDrive/src/Photone.git (fetch)
OneDrive file://Users/Pete/OneDrive/src/Photone.git (push)


From this point onwards I use SourceTree. However, if you use the command line then a couple of extra steps are required otherwise git complains. 

Firstly, when pushing if you just want to do:

git push OneDrive you need to tell git that the new OneDrive remote is the master. This is done by:

git push --set-upstream OneDrive master

Secondly, unless you've already set the push.default setting or just use 'git push --all' then you'll need to decide which option you want. The help from git describes these well:

Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

If you're using the remote clone as a backup then perhaps the original, i.e. matching behaviour is desirable. Whilst I use OneDrive this configuration should work for any other file synchronisation service, e.g. iCloud, DropBox or a standard mounted File System, e.g. Samba, NFS etc.

Swift Enums and Protocols

I'm trying to clear out my inbox before Christmas and I noticed an emails to myself entitled 'Enum question. Add protocol to enum?'.

The short answer is yes. The longer one. Take the following protocol

protocol Foo
{
func f() -> Void
}

A simple enum can be created that implements it:

enum Test: Foo
{
case One
func f()
{
print("Hello")
}

}

So the following short program:

let baz = Test.One

baz.f()

generates the output:

Hello
Program ended with exit code: 0

The protocol can also be implemented by extension so the following is equivalent and produces the same results:

extension Test: Foo
{
func f()
{
print("Hello")
}
}

It's not surprising that Swift's enum types support protocols. Off the top of my head I can't think of any clever reasons why you'd have enums implement a protocol. Given an enum is a first class type in Swift then it makes perfect sense. In fact it's documented on page 424 in The Swift Programming Language.

Tuesday, 27 October 2015

Things I learnt from Swift Summit

I attended the first Swift Summit on 21st of March; there were two days but I only went to the first. Here are some of the facts I learned:
  • Int is not a fundamental type as you would think of it in most languages. 
    • Instead it's a struct that derives SignedIntegerType with the actual value being an instance of the really fundamental type Bultin.World
    • Being a struct means it's a proper object hence its methods, the ability to extend (see later) and can (& does )implement protocols
  • Int can be extended
    • As it's an object (see above) it's possible to write extensions methods.
  • I have a far better understanding of what @autoclosure does now
    • It basically captures  the function rather than invoking it
  • nil is never actually treated as nil when used
And now for some opinion about the day.
  • People seem to be struggling with error handling
    • A couple of talks presented code to avoid pyramids of doom in regard to making a call, checking for success/failure and if successful continuing.
  • People think they're doing Functional Programming
    • Just because Swift supports Functional Programming style and some people use elements of FP they assume Swift is mainly a Functional language and that they are doing Functional Programming.
    • Passing functions arounds as first-class objects does not make your program functional
  • Some people now hate Objective-C

Thursday, 10 September 2015

A slight enhancement on Developing tvOS Apps with Swift

Apple announced tvOS yesterday. Downloading Xcode 7.1 Beta comes with the SDK and simulator for tvOS apps. The official documentation starts to run through how to create a basic app but is doesn't mention where to place and load the JS from and the same for the TVML.

Fortunately and vert quickly Jamerson Quave put together a tutorial.

I followed the Apple docs but checked Jameson's tutorial to verify the missing declaration of

var appController: TVApplicationController?

from AppDelegate and also for the JS and then TVML loading. I don't understand and the docs don't seem to see where the JS & TVML should be loaded from. They seem to suggest it should be remote, i.e. not part of the App Bundle but I don't know why. Anyhow I thought I'd see if I could.

The following assumes you've got to the end of Jameson's tutorial.

Loading the JS file; that then loads the TVML is easy. Add main.js to your application and change the lines within application:didFinishLaunchingWithOptions in AppDelegate.swift from:

let jsFilePath = NSURL(string: "http://localhost:8000/main.js") let javascriptURL = jsFilePath! appControllerContext.javaScriptApplicationURL = javascriptURL!

To

guard let jsUrl = NSBundle.mainBundle().URLForResource("main", withExtension: "js") else
{
    return false
}

This just loads the Javascript file (main.js) from the bundle instead. It's not a great improvement but it removes one dependency on the local web server.

I then tried to add hello.tvml to the bundler and modify main.js to create the fetched (via XmlHttpRequest). Unfortunately I couldn't create the Document in the JS. It seems that the normally (I've not done JS in a long time so what do I know) available document object isn't available to more documents and/or elements can't be created.

An attempt to create one, i.e.

var otherDoc = Document()

gives

015-09-10 21:53:50.213 tv1[55699:1483712] ITML <Error>: Document is not a function. (In 'Document()', 'Document' is an instance of IKDOMDocumentConstructor) - file:///Users/pete/Library/Developer/CoreSimulator/Devices/C2E7E5BD-1823-48BF-89E9-D3A499EE778A/data/Containers/Bundle/Application/F9C514E1-1A95-46A8-83D1-1BC96BC9A220/tv1.app/main.js - line:18:25

The objects mentioned in the TVJS documentation don't seem to be able to create one either.

Anyway, hopefully another small step. Full source on github.

A good be being dumb here and another look at the docs & samples suggests that writing apps. via JS is just one way and that a more iOS like app. can be written. Perhaps this is similar to Windows Metro that had both a JS and .Net (C#) version of WinRT; & C++ for completion.

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.