Thursday, 2 August 2012

Notes: Sharing to Google+ on IOS

It has been a long time since I touched any IOS code, so I was quite looking forward to a chance to do some when the IOS team within Google+ released the SDK into preview at Google I/O last month. Luckily, the documentation on the SDK page on developers.google.com is excellent, and covers the basics of the setup, but in part because I've forgotten almost everything about XCode and IOS, I thought it best to just write down what I did and what I encountered, primarily as an Aide-mĂ©moire for the future. Anyone building a new app should follow the documentation - but perhaps some developers will hit an issue I did and get something out of this post!

First things first, I had to set up a new OAuth2 client id at the API developer console with permissions for the Google+ API (I also added the Google+ History API, though this app does not use it so far). Next I created an OAuth2 client id for an installed application. It's important to make sure that the bundle ID specified here matches the one in Xcode, or the OAuth process wont work properly!

In Xcode (for reference, this was version 4.2), I created a new project, and following the docs added the Security and SystemConfiguration frameworks, and added the ObjC and -all_load flag to my linker settings. This is done by going to the target for you project, selecting Build, changing the display option from Basic to All and looking under the Linking panel.


Trying to drag up specifics of actually writing an Objective-C was quite a challenge, but I did manage to include the GooglePlusShare.h file in my main controller .h file, define an property for the GooglePlusShare object itself, and instantiate it it in the viewDidLoad function, using the clientid from the oauth2 console. The client ID I stored in the AppDelegate, wrapping a static NSString with a class function, as the sample app supplied with the SDK does. That can be retrieved in the controller by adding the app delegate header, and calling the clientId function. 


And in the controller, this can be retrieved like this:



To get the basic project building, I had to create a new group and add in the Google+ lib files (libraries and headers) from the lib directory, and the contents of the OpenSource directory in the SDK, which I split into the GTL and GTM folders mostly for aesthetics:



However, I had a number of errors of the sort "GTLBatchResult.m:31:26:{31:68-31:79}: error: ARC forbids explicit message send of 'autorelease' [4]", which the FAQ suggests can be avoided with adding the -fno-objc-arc  flag to the Compile Sources under Build Phases. The entry field is found by doubleclicking on the file - or selecting a bunch and hitting enter. 


That got the basic app compiling, but to actually do something requires a few more steps. Firstly I added a sharing function to the controller that just shares a static URL, defining the following function in the .m and declaring it in the .h



The next step was to add a UIButton to the main screen in the Storyboard editor to give something to share from, and right click on the button and drag from from UI Touch Up Inside event to the controller, and the didPressShare function. At this point firing up the app gave a share screen, but the actual sharing failed to return to the app - as I'd forgotten to setup the URL type as described in the documentation! This is used as the callback from the sharing process (which happens in the browser) and defaults to using the bundle name as the URL scheme. Once I registered the URL type in the Targets > Info panel, the sharing dialogue returned me to the application afterwards properly. 



Finally, I wanted some degree of confirmation that the user had shared, and the share object can use a finishedSharing call back for exactly that. I added a function to just pop up an alert when sharing had completed to the controller .m file.


To actually trigger this, we need to set the share object to have the controller as the delegate, so in the viewDidLoad function of the controller I added a line:


This sets up the share dialogue, but doesn't call the message alert. This is because return call using the URL needs to be specifically handled by the application, and control passed to the GooglePlusShare object. I needed to do a little more work in order to get the flow of control to move properly. Firstly, in the AppDelegate I needed to create a property for the share object, and setup checking the URL on open: 

AppDelegate.m

AppDelegate.h

And in the ViewDidLoad on the controller where I instantiate the share object, I need to share the pointer with the AppDelegate: 


This got the basic sharing happening - when the user presses the button, they're sent to plus, and can choose which circles to share to. Once done, they return to the app, which can take whatever action is needed.