Monday, April 18, 2016

Watch tutorial 2: Watch Architecture

This post is the second post of a set of short tutorials on Watch. If you want to see the previous post. In this tutorials, you're going to build your first AppleWatch app: DoItCoach.

Let's start by talking about what is an Watch app...

How does a watch app work?

First thing to know about AppleWatch app is that is always come bundles with its companion iOS app. It's the same idea as the App extensions introduced in iOS8, where you have a main iOS app and you can add extensions. Those extensions are embedded into Today, Shared (depending on their type) component. Like Extension, for AppleWatch app, you create an app project which comes with several build targets.

A Watch app consists of two separate bundles that work together.
  • WatchKit App: contains the storyboards and resource files needed to display your interface.
  • WatchKit Extension: contains the code needed for your native AppleWatch app. This is the part to get compiled and the binaries get transferred to your watch.

Side note: WatchOS vs watchOS2

As a side note, I think it's interesting to look back and know the differences between watchOS (the first version released in April 2015) and watchOS2 (released in September 2015). An image is worth a thousand worlds:


Now In watchOS 2, the extension runs on the user’s Apple Watch instead of on the user’s iPhone, as was the case in watchOS 1. This is the fundamental change for watchOS2: you can run watch native apps. The separation into Watch app / Watch Extension makes even more sense in the context of WatchOS1 as the binaries were deployed in different physical targets. In watchOS2, there is still the distinction of Watch app (storyboard, resources) and Watch extension (code binaries) although both are deployed natively to the AppleWatch.

The separation between WatchKit App and WatchKit Extension also means that the app's user interface is static and can't be changed at runtime. Adding or removing elements, for example, isn't possible. You can show and hide user interface elements though (I'll tell you more about that in Layout tutorial). This is done this way to save Watch resources so that it doesn't drain the battery.

Having the code binaries deployed natively makes your apps launch quicker, and be far more responsive as you remove the bluetooth latency. It also changes drastically the way you communicate/synchronize data between AppleWatch and its companion app. I tell you more about that in WatchConnectivity tutorial.

You now need to share a common business model between you iOS app and your Watch app. For that purpose, I like to separate the business model in a Shared group. This group is included in both iOS and Watch Extension target so it gets compiled and deployed on both.

Shared business model

Before you start coding,have a look at the shared business model. This model is used in the iOS app and will also be used in the Watch to represent a Task. Looking at the Task protocol:
public protocol Task: CustomStringConvertible {
  var name: String {get}
  var duration: NSTimeInterval {get}
  var startDate: NSDate? {get set}
  var endDate: NSDate? {get set}
  var timer: NSTimer? {get set}
  var type: TaskType {get set}
  func start()
  func stop()
...
}
We see a Task has a name, a duration, a startDate and endDate and two methods to start and stop the Task.

Ready for some code?
3, 2, 1... Go

Get starter project

In case you missed Watch tutorial 1: Which app?, here are the instructions how to get the starter project. Clone and get the initial project by running:
git clone https://github.com/corinnekrych/DoItCoach.git
cd DoItCoach
git checkout step1
open DoItCoach.xcodeproj

Create your Watch targets

To add an AppleWatch deployment target, in Xcode:
  • Go to File -> New -> Target...
  • Under watchOS, select Application tab and then choose WatchKit app
  • In product name enter DoItCoach WatchKit App
  • Untick all include scene, hit Finish button
  • Click yes when Xcode prompts you to activate Apple Watch schema
If prompted: Activate “DoItCoach WatchKit App” scheme?, answer yes.



You should now be able to see your the new target: DoItcoach Watch App, Xcode should have created its matching schema:



You've just created your first Watch app, but if you run the appleWatch screen is all black :(

Let's add a label

In Xcode:
  • Go to newly created Group named DoItCoach Watch App
  • Select Interface.storyboard, in the bottom right hand side Object Library search for a Label UI control.
  • Drag and drop the label onto your main screen
  • In Attributes Inspector:
    • in Alignment section, select Horizontal: center
    • change Text Color to Blue
    • in Font select System, UltraLight 17

Build and Run


To run in the simulator

Select DoItCoach WatchKit App schema with iPhone6sPlus + AppleWatch - 42 mm as targeted simulators.
The command should start both simulators and launch the iOS app and the AppleWatch app. In Xcode, in the left hand side Debug Navigator, you can see debug information for each app.



Note: Sometimes, Xcode failed to attache the debug process of the iOS app, you can do it manually:
  • either by selecting the schema that is not launched and run it again.
  • or by manually attaching the iOS app debug process to Xcode. It quite simple and I think this blog post explained it well

To run on Watch

When you want to run your app on Watch, plug your phone to a USB port, and keep you watch close by. You can install the app on your phone:
  • either by selecting DoItCoach WatchKit App schema with your iPhone and Paired Watch. This way, you can install the app in debug mode.
  • or by selecting by selecting DoItCoach schema with your iPhone selected. Open Watch app, in General -> App Install section, make sure Automatic App Install is checked. Once the app is installed on your iPhone, its Watch app will be automatically installed on your Watch. With this approach you won't be able to debug your Watch app but the install might be quicker.


  • Get final project

    If you want to check the final project, here are the instructions how to get it.
    cd DoItCoach
    git checkout step2
    open DoItCoach.xcodeproj
    


    What's next?

    With this first introduction tutorial, you saw how the Watch app is architectured:

    To sum up, an AppleWatch project is typically build three main parts: iOS app (iOS storyboard, iOS code), Watch app (watch storyboard), Watch extension (Watch code).

    You also created you first AppleWatch target, see how to build and run the apps on simulators or iPhone/paired Watch. You are now ready to add more UI controls on your watch screen. See Watch tutorial 3: Layout.

    Watch tutorial 1: Which app?

    This post is the first post of a set of short tutorials on Watch. In these step by step tutorials, you're going to build your first AppleWatch app. Yay!

    I'll guide you through. No prior knowledge on watchOS2 is required, but some basic iOS development skills (storyboards usage) and Swift language knowledge are assumed.

    When designing for an AppleWatch, you should keep the features simple. Bear in mind they'll have to work at on a 312 pixels wide by 390 pixels tall screen for a 42 mn watch. Don't try to fit too many features with a complexe screen hierarchy. Also, remember that your watch app comes with its iPhone companion app. Therefore, you don't need to fit all the features in the watch extension: a well chosen subset will do well.

    Let's start by talking about the app, you're going to build...

    DoIt Coach




    Have you ever wonder how to get more things done during the day, how to stay focus on your tasks? After all, getting your job done efficiently gives you more free time ;)

    Based on a well known time management technique, with DoItCoach, you break your day in small tasks interlaced with small breaks. DoItCoach's main goal is to be more efficient and stay healthy.

    Start the day, planning the list of task to be done. For the planification use the iPhone app. Add one task followed by one break. After a 3 of those add a longer break.

    Let's spice it up: since you want to stay fit in your life, you're going to try to do something physical during your breaks. Shorter breaks could be perfect for some weight lifting or curls ;) while longer breaks could be used for outdoor walk or short run.

    The iOS app

    Since the goal of this tutorial is about Watch app, you'll start with an initial project. All source code is available on github DoItCoach project for the final project.

    Starter project

    Clone and get the initial project by running those git commands:
    git clone https://github.com/corinnekrych/DoItCoach.git
    git checkout step1
    open DoItCoach.xcodeproj
    

    Build and Run

    open DoItCoach.xcodeproj
    
    Run the project in Xcode.

    You can add new task, move them and start the first task in the list. Once completed, the task is moved at the bottom of the list and a new one is available for you to start.

    What's next?

    With this first introduction tutorial, you saw how the iOS app DoItCoach worked. It's now your turn to work: let's add the AppleWatch target. See Watch tutorial 2: Watch Architecture

    Thursday, December 17, 2015

    Swift runs on Linux... But what about my favourite distribution?



    Swift is Open Source, you can install it on linux. Here is the instruction for an Ubuntu install. But wait... My favourite distribution is Fedora! Oh! Oh! Oh! I hear Santa Claus, I think it is time for a contribution: let's package Swift as a RPM!

    TL;DR: Download Swift RPM from here

    Building Swift on Fedora 23


    Here is a summary of my journey in trying to build Swift on Fedora:
    • I've started with a brand new install of Fedora23. I've downloaded the ISO from here and I run the install on a Virtual Machine.
    • As stated in System Requirements, there is a list of dependencies to fetch:
      • for Ubuntu
      • cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config
        
      • which translates into Fedora platform:
      • cmake ninja-build clang python-devel libuuid-devel libicu-devel libbsd-devel libedit-devel libxml2-devel libsqlite3x-devel swig gcc-c++ pkgconfig
        
      Notice libncurses5_dev and icu-devtools are not needed for Fedora, they seem to be fetched already either by transitive dependencies or a default of the platform.
    • Clone Swift github repo as an entry point
    • git clone https://github.com/apple/swift
      cd swift
      ./utils/update-checkout --clone
      
      Here I sticked to Swift documentation. update-checkout is a python script that will clone all the required repositories needed to build Swift from source. It will also make sure the directory structure matches the build's need. This is the directory structure you get:

      Notice how swift-lldb github repo matches lldb directory but swift-corelibs-foundation stays swift-corelibs-foundation :]
    • Install ninja
    • Ninja is the current recommended build system for building Swift. It turns out that ninja's little name on Fedora is ninja-build. But CMake calls it ninja, so I've symlinked ninja to point to ninja-build:
      dnf install -y ninja-build 
      sudo ln -s /usr/bin/ninja-build /usr/bin/ninja
      
    • Launch the build:
    • ./utils/build-script -t
      
      This is a basic build which will end up with binaries not packaged. Be aware that the build can be quite intensive on memory, I had my build crashed a couple of times. I had to restart it, but thanks goodness, it's an incremental build. On success, go to ../build/Ninja-DebugAssert/swift-linux-x86_64/bin, you'll find swiftc and you can write your first swift code but... This Swift runtime is missing lots of components. For example, to build foundation:
      ./utils/build-script -l -b -p --foundation
      
      and so on...
      There must be a better way! When in doubt, use the help command is my mantra. I found this statement about preset mode. Using buildbot_linux preset made the trick! Thanks man.

    Packaging in RPM


    My next step was to nicely packaged Swift into an RPM for any given Swift tag. I have to confess that I'm quite new to RPM packaging ;) So I get inspired by existing RPM like ninja-build. Besides, there is tons of documentation. I've used rpm.org quite a lot.

    While installing, the main issue I faced was: in Fedora, python2.7 is installed in /usr/lib64 and the CMakeList.txt is looking in lib, I workaround the issue by overriding lldb/scripts/CMakeLists.txt just before building and installing. Thanks sed. There might be better ways, I will look into making a PR to swift-lldb.

    Eventually I come up with this repo: https://github.com/corinnekrych/swift-rpm
    RPM can be directly downloading from release tab.

    Running Swift RPM


    Last but not least, to test the RPM, I've installed a brand new Fedora VM and run the following command:
    sudo dnf install libbsd python gcc-c++ clang
    sudo rpm -Uvh swift-2.2-SNAPSHOT20151210a.x86_64.rpm
    
    You want to see it in action?
    Clone a swift repo, I used Swifter. Run:
    git clone https://github.com/glock45/swifter.git
    cd swifter
    swift build
    

    The end


    I hope you've enjoyed my blog post. Feel free to contribute to the Swift RPM repo. Let's make Fedora and Swift best friends.

    Friday, June 26, 2015

    Playground revisited for Xcode7

    Yesterday I watched WWDC 2015 "What's new in Playground", snuggled down in my bed, ready to enjoy my session, better than a Luc Besson's movie ;)
    (yes that's the kind of things geeks do).

    I use playgrounds a lot.

    They are part of my Swift toolbox. Good ideas found on Twitter, things I experiment, I store them in my Swift github repo. Very practical too, to share recipes with others.

    If we look behind for a bit of history in playground releases (not to worry Playground and Swift are just one year old, so history will be short!).

    Looking behind...


    Xcode 6.0 beta brings playground. I'm convinced playgrounds have played a crucial role in the so rapid Swift adoption. Of course, playgrounds were quite buggy in beta and used to crash a lot but, with playgrounds, you can code Swift snippets, add text explanation to them to share with others. It's what the Swift guided tour offered you. You can even embed images ans CSS in Resources folder.

    Xcode 6.2 brings us markdown format, see my blog post Even more fun with Playground. To me, this was one of the biggest improvement: not to have to write fragments of explantation in HTML and then associate Swift files using some XML glue file... Markdown is just great! See my Swift playground in Xcode6.2 format.

    Xcode 6.3 brings us Sources folder. Like we used to have the Resources folder. So now to be able to test a Swift framework, you can put it in Sources. No need to work with a workspace like described in Playground and libraries post. We also have inline results, quite practical too. See my Swift playground in Xcode6.3 format.

    So what's new in Xcode7?


    Xcode 7 brings us Pages. I used to gather together all my Swift recipes in my toolbox within a workspace. With a workspace, I could also embed Swift library (prior to swift 6.3). But now with Xcode7, bye bye workspace, I'll stick to a single .playground file with different pages.

    You can navigate between pages using markdown syntax:
    [First Page](@first)
    [Previous](@next)
    [Previous](@previous)
    [Last](@last)
    
    You can even go to one of your pages using its name. For a full markdown syntax go and visit Apple prerelease markdown reference page.

    Enough talking, enough writing, let's convert my existing Swift toolbox into Swift2 and Xcode7 format. After trying the automatic Xcode Swift2 conversion (Go to: Edit -> Convert -> To Latest Swift Syntax), I gave up on that as it screwed up all my markdown and decided to migrate by hand. The code conversion was easy, the most tedious part was moving from .xcworkspace to one single .playground with multiple pages.

    A few minutes later....
    See my Swift playground in Xcode7 format.

    Where's to go from here?


    This year all WWDC videos are available to view to all developers, I encourage you to go through "What's new in Playground", a good video to enjoy with pop corn and coke.
    Another great place to look at is Erica's blog, I haven't checked out her iBook on playground yet, I keep it for another great evening ;)

    Last, do not forget to:
    Practice, practice, practice.
    Happy Swift2 playing!

    Saturday, June 13, 2015

    RivieraDEV is over... See you all next year!

    2 days of sun, sea and sushi...
    And great talks too!
    The conference made by developers for developers with the theme "we're not only coders".

    Here is some miscellaneous notes, mumblings and souvenirs from this edition.

    Thursday starts with a Duchess France presentation made by Blandine: as you've seen we not only located in Paris. If you want to get in touch, participate in such event, drop us a line on Duchess Google group.

    Some Design Pattern reloaded and polyglotism latter, out for lunch with great buffet and socca!

    For the afternoon, I had to miss Julien's presentation on Vert.x, as I was the speaker next room :]
    I've been pleased to see a full room for my Swift presentation. Sophia Antipolis might hold more iOS/OSX developers than I thought maybe time to start a cocoaheads meetup like Florian suggested. If you're interested tweet me. And for those of you who wants to explore Swift in more details, here is my slides with more links.

    I also missed the sushi cooking workshop coz I went to Sebastien's talk on 24 mins to build a web app. Although I know the talk by heart (I work with Sebi on AeroGear project), I never miss one of his talk, it's always fun and my favorite part is the 24 mins of live coding. Today on the menu was.... ShushiApp of course.

    Friday keynotes were very inspiring. From "what does innovation culture mean for Atlassian?" to "how your boost you professional karma" to end with "the code explained to my mum". I really liked Katia's talk, she's so good at story telling and the anecdote of the boomerang is very true.

    This edition will always be a special souvenir for me as it was he first time I've been on the other side: not only an attendee, not only a speaker but this year I was proud to wear the yellow T-shirt as part of the RivieraDEV team.

    What makes a good conference is not just the great talks, the quality of the food, the fun workshops, the affordable ticket... It's all about the people you meet. With a friendly atmosphere, it's easy to talk to any body. It's the place where you learn that Vert.x or Ceylon committers are also passionate sushi cookers. You can talk to Angular committer, meet the voice behind the cast coder, chat with one of the Duchess, see Nao, talk about kids or just bump into an ex-Amadeus co-workers.

    Thanks for the thanks guys, and see you all next year.

    Wednesday, June 10, 2015

    Swift new super power



    To me, the most sensational news that came out of this year WWDC is without any doubt Swift going Open Source next Fall. Swift (the compiler and standard library) running on Linux!

    I've started on Swift since day one with AeroGear libraries, switching from ObjC to Swift is quite change of paradigm. In my Swift journey, I learnt some "super powers" I like to talk about when I do presentations on Swift. See my slides for more super-hero drawings ;)

    Apple told us in 2014 when launching Swift: "It's Objective-C without the C" and it's going to be be its successor. In WWDC 2015, Craig Federighi said Objective-C was around for the last 30 years and Swift will be here for the next 20 years.

    It turns out that Swift is not Objective-C at all, but for sure it's here to stay :]

    Developers have understood it and it's no surprise to me that Swift is ranked 22nd at Redmonk indice with a fulgurant growth this year.



    Why do I like Swift so much?


    Its elegant syntax

    Just for not having to deal with block syntax agin, I love you Swift.
    Some have said Swift wasn't innovative, it got lot of family ressemblance from other langages. True, it takes advantage from the experience hard-won by many other languages said Chris Lattner in his blog.
    I like the consistent reusable syntax: I override subscript operator like I write computed properties etc... Easy.

    Playground is just fun

    Easy too, to get started with Swift. Download the Swift guided tour playground. With some REPL and hands-on, it's fun. I love how you can build your own toolbox with Swift playgrounds: mixing explanations and code snippets. See my previous post about it and I'm happy to share my toolbox with you.

    Open the way to new paradigms

    Swift opens the way to new paradigms: with a statically type language, generics, functions, closures, we've got the tools to do more functional programming. Immutability is right into Swift's heart. With constants and variables, Swift let you define what is immutable. Besides, almost all types in Swift are value types, including arrays, dictionary, numbers, booleans, tuples, and enums. Classes are the exception rather than the rule. Functional fun is not just for JVM language.

    Open Source as a new super power


    For the last year, when giving presentations on Swift, I've been regularly asked: What are Apple plans on open sourcing Swift?
    At last, we've got the answer!
    There is no doubt that going Open Source will fuel Swift progression, it will also, most probably open new opportunities.

    Future looks bright and as a Swift developer, we can contribute.



    Thursday, April 23, 2015

    How well does Swift play with iOS7?

    Swift was created with the Objective-C interoperability in mind. It's easy to get why, Swift playing nicely with Objective-C, was required in order to use existing cocoa API. At first, when trying interoperability, I mostly used Objective-C libs in my Swift apps. But, as I progress in my Swift immersion, I soon write reusable Swift code.

    Apple stated it from day one:
    • you can also use Swift code from Objective-C app
    • as Swift applications compile into standard binaries plus some Xcode bundling Swift bits in your app, you can run Swift code on iOS 7.
    You can run Swift code in iOS7 BUT there are several paths to drill down…

    Do you want to run a Swift app on iOS7?


    Let's talk about runtime


    How does iOS7 understand Swift? Does iOS7 operating system includes Swift support?

    Nope! It’s the other way around. Application with Swift code bundles Swift specific standard libs.

    From Colemancda's blog post:
    "With Swift, Apple has changed how standard libraries are shipped. With Objective-C, all of the standard libraries, system frameworks, and the runtime itself, were shipped with the OS. With Swift, Apple wanted the ability to quickly deprecate parts of the Swift Standard Library and also add new features. While these changes do break apps at the source code level, it would be a huge problem if shipped apps started to break because the standard library they are linked against has an incompatible API. Apple’s solution to the problem is to ship a specific version of the standard library with your app."

    Besides, reading Swift blog post about Compatibility, I found that this statement is interesting: "When the binary interface stabilizes in a year or two, the Swift runtime will become part of the host OS and this limitation will no longer exist."

    iOS8 brings a shinny new langage support: Swift but, the other correlated important change that happens is the way libraries are packaged. Running Swift on iOS7 also brings the question of how well Swift/Objective-C go together.

    Let's talk about Objective-C / Swift impedance


    So Swift code can be run even when called from Objective-C. Swift is a strongly type-safe language whereas Objective-C is dynamic by essence. It sometimes brings some blurry runtime behaviour (either crash or nothing happen) to watch out for when writing Swift code that aims to run on both Objective-C and Swift:

    • Swift pure object are not supported: you need to add @objc or inherit from NSObject if your class is visible from Objective-C.
    • Pay special attention to optional. I recommend this stackoverflow post for more reading.
    • Same goes when optionally casting.
    • Don’t use iOS8 api: of course… it seems obvious. But it's easy to forget tough and then you run into runtime exception - I say it from experience :))
    • Some enum support is available in Objective-C since Swift1.2.
    etc... I will go in more details in a later blog post.

    An interesting open source library which used the Swift first approach (code written in Swift first but compatible with Objective-C) is Quick. Most of the code is written in Swift some adapters in Objective-C are required when Swift paradigm won't fit (note: Quick and Nimble are DSL for BDD testing, DSL doe uses langage paradigm a lot).

    Let's see an example


    Here is an experiment I did: Run an HelloWorld app written in Swift on iOS7. That app registers to UnifiedPush Server. For this first experiment, let's just have one application with all the source code bundled together.

    You can clone the Xcode6.3 code source:
    git clone https://github.com/corinnekrych/unified-push-helloworld.git
    cd unified-push-helloworld
    git checkout ios7.experiment
    open HelloWorldSwift.xcodeproj
    
    and run it.

    To run the app you will need a device with iOS7 installed because push notification can not be run from simulator. Also make sure the UPS instance is live on OpenShift. Alternatively if my OpenShift instance is not running, create your own server following the UPS guide.

    Run the app on device. Go to UPS console, login with admin/admin. Go to "send message" right hand tab, and send a message. Your message should be displayed in the list of messages.

    Now what about if we want to extract the code related to the UPS registration in an external lib?

    Do you want to run Swift libs linked to Swift app on iOS7?


    Dynamic framework


    Swift libraries can only packaged using dynamic framework (sometimes called cocoa touch framework or embedded framework or bundled framework). Although dynamic frameworks are new to iOS8, they used to be used in OSX though for a while.

    With Swift, you can’t package your Swift libs statically because static libs would lead to multiple runtimes in the final executable. We’re back to the point we discussed earlier in …: With Swift evolves quickly and ship its a specific version of the standard library with your app.

    So you need to copy/paste your lib source code in your final app?

    Cocoapods to the rescue


    Or use cocoapods 0.36+ with the use_frameworks! option. I recommend you to read the excellent article from Marius: CocoaPods 0.36 - Framework and Swift Support. Behind the scene, cocoapods ensures all dependant libraries are bundled together with the same set of dylibs, which are embedded into the Frameworks subdirectory of the application bundle.

    Using cocoapods brings an easy tooling to support dynamic framework with Swift.

    Let's see an example


    Let's take an simple app ChuckNorrisJoke (Yes! Chuck Norris is in the place) from aerogear-ios-cookbook written in Swift and let's use aerogear-ios-http (Swift too) an run the app on iOS7.

    Originally aerogear-ios-http was designed with minimal deployment target to 8.0, in this experimental branch, I'm going to lower the deployment target to 7.0 and adjust some of the Swift code to fit iOS7.

    git clone https://github.com/corinnekrych/aerogear-ios-cookbook-1
    git checkout ios7.support
    cd aerogear-ios-cookbook/ChuckNorrisJokes
    pod install
    open ChuckNorrisJokes.xcworkspace
    
    Run on iOS7 device or on iOS7 simulator and enjoy chuck Norris humour :)

    Take away


    As we've seen, swift code can run on iOS7 and iOS8 but comes with some compromises:
    • writing code that comply with both Objective-C and Swift.
    • dynamic framework packaging. Using cocoapods takes some of the burden away.
    • last but not least, it certainly requires some extra testing as most of the errors will happen at runtime.
    Swift is moving fast, and as we've seen the latest version (Swift 1.2 with iOS that ships with iOS8.3) brings improvement for compatibility with Objective-C (enum case). Interoperability is key to achieve developer's Nirvana of "easy maintenance": write once, deploy on both iOS7 and iOS8.