Friday, August 28, 2015

My Watch's HelloWorld

My post today is all about: Yes I did it!

Not just a HelloWorld on Watch
It's MY HelloWorld on MY Watch.

Okay, it may sounds very childish but hey it's not everyday you feel like a super hero having completed one of your geeky evening. Tonight, I defeated the dark forces: I managed to install watchOS2 beta5 on my watch, compiled, run and deployed my first Swift HelloWorld App on my watch.

I want to share with you my first experience and give you some tips and useful workarounds.

To start with, you need

In this tutorial we're going to show how to run an app on actual device.
You'll need:
  • Watch with WatchOS2 beta5 installed
  • iPhone with iOS9 beta5 installed
  • Xcode7 beta6

  • Start a new project

  • Open Xcode
  • Go to File -> New -> Project...

  • Choose watchOS -> iOS App with WatchKit App

  • Name your project MyHelloWorld, uncheck all boxes, we keep it simple :)
  • Go to MyHelloWorld WatchKit App folder, select Interface.storyboard
  • Add two labels, fill in with your personal Hello
  • Now time to run it!

    Run it on emulator

    Select your emulator either 30 or 42 mm.

    Run it on device

    You will need a bit of patience here, but here we go:

    If you run into...

    This is my troubleshooting notes. Hopefully you're done and all happen right, you can skip this paragraph and go to You're done section.

    Apple watch not paired

    The target is not reachable, Xcode is telling you "Watch not paired" or even no watch at all.
    Unplug, replug your iPhone. Go to Product -> Destination and select your iPhone + Watch.

    Spinning Wheel

    If you run into infinite spinning wheel on your watch, try this workarouand as described in this Apple Forum thread:

    Watch apps written with Swift code may not install to the Watch from the phone.
    Workaround: Add STRIP_BITCODE_FROM_COPIED_FILES=NO as a user-defined build setting on the iOS, watch, and extension targets (or just add it as a project default).

    Disappearance of your app on the watch

    You may run into a case where you can run your app from Xcode into you Watch but once you stop it, the app disappears from the watch. As a workaround you can install you iOS app as an archive. Follow the steps below:

  • build an ipa
    • go to Xcode Product->Archive
    • in the archive popuphit “Export…” button,
    • choose "Save for Dev Deployment"
    • select Export one app for all compatibles devices
    • all target, export
  • install ipa via iTune
    • go to list of all apps drag and drop the *.ipa
    • go to iPhone device, Apps, choose newly install app click intall and sync

    You're done

    You're ready to show off your first Watch app to your geeky friends... Or maybe wait a bit, start looking into WatchKit and see what you can code further ;)

    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)
    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
    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
    git checkout
    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.

    Thursday, February 26, 2015

    Even more fun with playground in Xcode 6.3

    I've just installed Xcode 6.3, it brings us even more fun with playground!

    Last summer, I blogged about playground and how you can use them to do great interactive tutorial. With playgrounds... It's love at first sight. ❤ ❤ ❤ ❤

    I think they are great learning tools. Apple's Guided tour made them popular from day 1.

    I even use them in my lib repositories to demo how to use an API. For that simply, create a workspace with your framework code and attach a playground file. See playground has never been so fun for more details and check out Alamofire lib usage of playground.

    When I first gave a presentation on Swift, I decided to write it with playground of cource :P
    But, how to write your own guided tour?

    At first, there was HTML...

    Playgrounds are directory that can contain: resources (images, html), swift source (.swift file) and a description file (contents.xcplayground) to help rendering.

    You define HTML page in Documentation folder, Swift source file directly under playground folder. Then using contents.xcplayground descriptive file you associate the different fragments together. As you're working with CSS, you can also customize you're own CSS. Don't specify too much the size etc... let Xcode preferences deal with that.

    With Xcode 6.2, it renders as:

    The annoying part, is when you open your playground and start changing the source file section, Xcode will generate a new file number: section-1.swift will become section-2.swift and so on...
    Slightly annoying, I have to confess.

    Then markdown-to-playground processing

    Then emerged swift-playground-builder an open source project which takes a markdown input and generates a playground out of it. And that indeed, makes your life easier, you don't have to switch between source code and documentation file. But...

    I'm afraid there is a 'but'. The main drawback is: as you write your tutorial you can't check your Swift syntax. You're in markdown file!

    I personally prefer to stick to real source file and html.

    To end up with markdown everywhere!

    With markdown directly in swift source code, you can write source code and tutorial text at the same time by using special comment ```//:``` :
    //: ### Immutability
    //: ```let``` for constants => cannot change once initialized
    //: ```var``` for variable => can be changed and can be optional. let name = "julie" let age = 18 println("Hello my name is \(name) and I am \(age) years old")
    And it renders as:

    The only slight 'but' here is about refreshing...
    Difficult to write your comment in Xcode directly and have them refreshed. I usually work with Xcode opened for rendering and another editor for editing, triggering refreshing but switching Xcode current file. Caution when modifying contents.xcplayground, Xcode is picky on this and may get upset (yeah! good old Xcode crash are not gone!)

    Writing interactive tutorial is really easy with Xcode 6.3. Follow the links if you want to see the source code of the Swift tutorial I've talked about in xcode 6.1 format or with the latest 6.3 format.
    Happy Swifting!

    Monday, January 12, 2015

    Sharing Keychain access in a Share Extension

    I've been wanted to do a blog post on how to achieve SSO on iOS using sharing Keychain for a bit...

    And at the same time, I also wanted to try app extension very badly. So in an attempt to get the best of the two worlds, let's talk about writing a share extension to an app which need to store OAuth2 access token in a secure manner. We'll see how to share Keychain content through group-id between an app and its extension.

    Remember Shoot'nShare app?
    A simple app that takes pictures and allows you to share them with Facebook, GoogleDrive or even your own Keycloak backend. If we want to learn more about it, visit previous blog posts: To simplify, in this blog post we will focus on sharing to Google Drive only. As a pre-requisite, let's start creating a Google project.

    OAuth2 Google Set up

    If you want to create a google project to use for uploading files to Google Drive, follow the steps below:
    • Have a Google account
    • Go to Google cloud console, create a new project
    • Go to APIs & auth menu, then select APIs and turn on Drive API
    • Always in APIs & auth menu, select Credentials and hit create new client id button Select iOS client and enter your bundle id.
    • NOTES: Enter a correct bundle id as it will be use in URL schema to specify the callback URL. Please use your own unique BUNDLE_ID with format like org.YOUR_DOMAIN.Shoot replacing YOUR_DOMAIN with your actual domain.
    Once completed you will have your information displayed as below:

    Now that we've got your google project set up, let's add an Share Extension to Shoot app and see what's involved.

    Share Extension

    What it is?

    An App extension add feature to an existing application. There are several types of extensions. The one we're interested in today is the share extensions. As the name says it all, this extension lets you share content with the external world. By default Xcode template will inherit from SLComposeServiceViewController. Therefore when hitting share button, a pop-up appears to send a message with image. Before iOS8, only a handset of providers were available to share content with. Those providers were defined directly in the operating system directly so the list was not flexible at all. Those days are over (yay!), you can now share with your favourite or even your own social networks directly from Photos app. This is exactly what we're going to do: let's share to GoogleDrive from Photos app via Shoot'nShare app.

    One important thing to bear in mind extensions are not deployed by themselves. They must be packaged within a container app. Concretely in Xcode extensions are extension target within you container app.

    Let's see an example

    1. Get the project
    Code source can be found in aerogear-ios-cookbook app.extension branch. Clone the repo and select the correct branch:
    git clone
    git checkout AGIOS-224.shoot-extension
    2. Define you own bundle_id
    To be able to work with extension you need to enable App Groups. App Groups are closely linked to bundle identifiers. So let's change the BUNDLE_ID of the project to match your name. Select the Shoot project in the Project Navigator, and then select the Shoot target from the list of targets. On the General tab, update the Bundle Identifier to org.YOUR_DOMAIN.Shoot replacing YOUR_DOMAIN with your actual domain. Do the same for the extension target: select the Shoot project in the Project Navigator and then select the ShootExt target. On the General tab, update the Bundle Identifier to org.YOUR_DOMAIN.Shoot.ShootExt replacing YOUR_DOMAIN with your actual domain.

    3. Configure App Group for Shoot target
    In order for Shoot'nShare to share content with its extension, you’ll need to set up an App Group. App Groups allow access to group containers that are shared amongst related apps, or in this case your container app and extension. Select the Shoot project, switch to the Capabilities tab and enable App Groups by flicking the switch. Add a new group, name it, again replacing YOUR_DOMAIN with your actual domain.

    4. Configure your App Group for ShootExt target
    Open the Capabilities tab and enable App Groups. Select the group you created when setting up the Shoot project. The App Group simply allows both the extension and container app to share files. This is important because of the way files are uploaded when using the extension. Before uploading, image files are saved to the shared container. Then, they are scheduled for upload via a background task.

    Sharing Keychain

    With the same idea of sharing group between apps (or app and extension) to be able to have a common space for saving files, we can use Keychain group so that app and extension can share Keychain items. In our case we want a common space for Shoot app and Shoot Ext to share OAuth2 access token.

    1. Configure Keychain Sharing for Shoot target
    In order for Shoot'nShare to share access tokens with its extensions, you’ll need to set up a Keychain Sharing Group. Select the Shoot project in the Project Navigator, and then select the Shoot target from the list of targets. Now switch to the Capabilities tab and enable Keychain Sharing by flicking the switch. Add a new group, name it org.YOUR_DOMAIN.Shoot, again replacing YOUR_DOMAIN with your actual domain.

    2. Configure Keychain Sharing for ShootExt target
    Select the Shoot project in the Project Navigator and then select the ShootExt target. Open the Capabilities tab and enable Keychain Sharing. Select the group you created when setting up the Shoot project.

    3. Configure Shoot App code
    In Shoot/ViewController.swift modify:
        @IBAction func shareWithGoogleDrive() {
            let googleConfig = GoogleConfig(
                clientId: "",
            let ssoKeychainGroup = ""
    where YOUR_APP_ID_PREFIX is a unique alphanumeric identifier, you can view it on dev center:
    and org.YOUR_DOMAIN.Shoot is you BUNDLE_ID.

    4. Configure ShootExt code
    In ShootExt/ViewController.swift modify:
        let ssoKeychainGroup = ""
        let appGroup = ""
        override func didSelectPost() {      
            // We can not use googleconfig as per default it take your ext bundle id, here we want to takes shoot app bundle id for redirect_uri
            let googleConfig = Config(base: "",
                    authzEndpoint: "o/oauth2/auth",
                    redirectURL: "org.YOUR_DOMAIN.Shoot:/oauth2Callback",
                    accessTokenEndpoint: "o/oauth2/token",
                    clientId: "",
                    refreshTokenEndpoint: "o/oauth2/token",
                    revokeTokenEndpoint: "rest/revoke",
    the constant ssoKeychainGroup with your YOUR_APP_ID_PREFIX + BUNDLE_ID.
    the constant appGroup with your App Group
    in google config, redirectURL should match your BUNDLE_ID

    5. Run the extension
    To run shoot extension, select ShootExt target and run it, select Photos app as host app.
    Select a photo, click on share button and select Shoot app. A Pop-up will appear, select send: you photo is uploaded on the background... and we're done. We've done all the configuration needed. Let's look at the code now.

    Spot the Difference

    Actually what we want to do from Share extension is basically the same as we do from Shoot'nShare app. But we do in an extension to allow us to do from Photos app. What about playing the difference game? What are the differences between uploading from Shoot'nShare app or uploading from ShootExt?

    1. you can not trigger the OAuth2 danse from the extension
    Extensions have limitations. Some API are not available. An app extension cannot access a sharedApplication object, and so cannot use any of the methods on that object. Difficult to trigger an external browser to launch the OAuth2 danse. Opening the container app in case no access tokens is available could be an alternative... However this alternative is offered only for today widget extension...

    Indeed depending on extension type, some actions are allowed or forbidden. For example quoting apple doc : "only a today widget (and no other app extension type) can ask the system to open its containing app by calling the openURL:completionHandler: method of the NSExtensionContext class."

    With our ShootExt, it would have been handy to be able to open Shoot'nShare app if no access token is available in the shared keychain. As our extension is a share extension, this is not available. As a result, we take as a pre-requisite that the end user has already shared a photo from Shoot'nShare app before using the extension. To do so we override OAuth2Module's requestAuthorizationCode method:
    public class OAuth2ModuleExtension: OAuth2Module {
        // For extension we do not want to be redirected to browser to authenticate
        // As a pre-requisite we should have a valid access_token stored in Keychain
        override public func requestAuthorizationCode(completionHandler: (AnyObject?, NSError?) -> Void) {
            completionHandler("NO_TOKEN", nil)
    In case there is no token, we will return an error message to the end user asking him to use Shoot'nShare first.

    2. you use the same redirect-uri OAuth2 for both extension and app
    To do so, in ShootExt/ViewController.swift we can not use GoogleConfig class, we'll have to use Config class ans spscify shoot'nShare's redirect url as shown below:
            let googleConfig = Config(base: "",
                    authzEndpoint: "o/oauth2/auth",
                    redirectURL: "org.YOUR_DOMAIN.Shoot:/oauth2Callback",
                    accessTokenEndpoint: "o/oauth2/token",
                    clientId: "",
                    refreshTokenEndpoint: "o/oauth2/token",
                    revokeTokenEndpoint: "rest/revoke",

    3. you need to save in the Keychain using group-id
    When we first save the access token in Shoot'nShare app, we need to specified the group-id, in Shoot/Viewcontroller.swift, we modify shareWithGoogleDrive method to accomodate it: In line7-10 we create a TrustedPersistantOAuth2Session object with a keychain group-id:
        @IBAction func shareWithGoogleDrive() {
             let googleConfig = GoogleConfig(
                clientId: "",
            let ssoKeychainGroup = ""
            // We specify the keychain groupId, should be the same as the one used in Share extension
            let gdModule = OAuth2Module(config: googleConfig, 
                                        session: TrustedPersistantOAuth2Session(accountId: 
                                                   groupId: ssoKeychainGroup))
            self.http.authzModule = gdModule
            self.performUpload("", parameters: self.extractImageAsMultipartParams())

    4. you upload your photo in the background
    Last but not least, when dealing with extension, remember that action will take place in the background! In our case we want to perform a multipart upload (we're using multipart Google endpoint) in the background. using aerogear-ios-http you can perform multipart background upload either using upload method with stream or file as shown line 28. It's also possible to use a POST method with multipart params (behind the scene a NSURSLSession upload is performed):
        override func didSelectPost() {
            let googleConfig = ....
            // Create a TrustedPersistantOAuth2Session with a groupId for keychain group sharing
            let gdModule = OAuth2ModuleExtension(config: googleConfig, session: 
    TrustedPersistantOAuth2Session(accountId: "ACCOUNT_FOR_CLIENTID_\(googleConfig.clientId)", 
    groupId: ssoKeychainGroup))
            self.http.authzModule = gdModule
            gdModule.requestAccess { (response: AnyObject?, error: NSError?) -> Void in
                var accessToken = response as? String
                if accessToken == "NO_TOKEN" {
                    println("You should go to Shoot app and grant oauth2 access")
                } else {
                    let imageURL = self.saveImage(self.imageToShare!, name: NSUUID().UUIDString)
                    // multipart upload
                    let multiPartData = MultiPartData(url: imageURL!,
                                mimeType: "image/jpg")
                    let parameters = ["file": multiPartData]
                    // multi-part upload could be achievd either with upload as a stream or using POST
                             stream: NSInputStream(URL: imageURL!)!, 
                             parameters: parameters, 
                             method: .POST, 
                             progress: { (ar1:Int64, ar2:Int64, arr3:Int64) -> Void in
                        }) { (response: AnyObject?, error: NSError?) -> Void in
                        println("Uploaded: \(response) \(error)")

    Hope your find this blog post useful and remember: it's all about Sharing...
    Do not hesitate to share this link :)