iOS – Sharing file path between a share extension and iOS app

Here’s an app store accepted way to share file path between an extension and an app.

  1. Share extension
#import "ShareViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>
//Macro to hide post dialog or not, if defined, will be hidden, comment during debugging

@interface ShareViewController ()


@implementation ShareViewController

NSUInteger m_inputItemCount = 0; // Keeps track of the number of attachments we have opened asynchronously.
NSString * m_invokeArgs = NULL; // A string to be passed to your AIR app with information about the attachments.
NSString * APP_SHARE_GROUP = @"";
const NSString * APP_SHARE_URL_SCHEME = @"schemename";
CGFloat m_oldAlpha = 1.0; // Keeps the original transparency of the Post dialog for when we want to hide it.

- (BOOL)isContentValid {
// Do validation of contentText and/or NSExtensionContext attachments here
return YES;

- ( void ) didSelectPost

[ self passSelectedItemsToApp ];
// Note: This call is expected to be made here. Ignore it. We'll tell the host we are done after we've invoked the app.
// [ self.extensionContext completeRequestReturningItems: @[] completionHandler: nil ];
- ( void ) addImagePathToArgumentList: ( NSString * ) imagePath
assert( NULL != imagePath );

// The list of arguments we will pass to the AIR app when we invoke it.
// It will be a comma-separated list of file paths: /path/to/image1.jpg,/path/to/image2.jpg
if ( NULL == m_invokeArgs )
m_invokeArgs = imagePath;
m_invokeArgs = [ NSString stringWithFormat: @"%@,%@", m_invokeArgs, imagePath ];

- ( NSString * ) saveImageToAppGroupFolder: ( UIImage * ) image
imageIndex: ( int ) imageIndex
assert( NULL != image );

NSData * jpegData = UIImageJPEGRepresentation( image, 1.0 );

NSURL * containerURL = [ [ NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier: APP_SHARE_GROUP ];
NSString * documentsPath = containerURL.path;

// Note that we aren't using massively unique names for the files in this example:
NSString * fileName = [ NSString stringWithFormat: @"image%d.jpg", imageIndex ];

NSString * filePath = [ documentsPath stringByAppendingPathComponent: fileName ];
[ jpegData writeToFile: filePath atomically: YES ];

//Mahantesh -- Store image url to NSUserDefaults

NSUserDefaults *defaults=[[NSUserDefaults alloc] initWithSuiteName:@""];
[defaults setObject:filePath forKey:@"url"];
[defaults synchronize];

return filePath;

- ( void ) passSelectedItemsToApp
NSExtensionItem * item = self.extensionContext.inputItems.firstObject;

// Reset the counter and the argument list for invoking the app:
m_invokeArgs = NULL;
m_inputItemCount = item.attachments.count;

// Iterate through the attached files
for ( NSItemProvider * itemProvider in item.attachments )
// Check if we are sharing a Image
if ( [ itemProvider hasItemConformingToTypeIdentifier: ( NSString * ) kUTTypeImage ] )
// Load it, so we can get the path to it
[ itemProvider loadItemForTypeIdentifier: ( NSString * ) kUTTypeImage
options: NULL
completionHandler: ^ ( UIImage * image, NSError * error )
static int itemIdx = 0;

if ( NULL != error )
NSLog( @"There was an error retrieving the attachments: %@", error );

// The app won't be able to access the images by path directly in the Camera Roll folder,
// so we temporary copy them to a folder which both the extension and the app can access:
NSString * filePath = [ self saveImageToAppGroupFolder: image imageIndex: itemIdx ];

// Now add the path to the list of arguments we'll pass to the app:
[ self addImagePathToArgumentList: filePath ];

// If we have reached the last attachment, it's time to hand control to the app:
if ( ++itemIdx >= m_inputItemCount )
[ self invokeApp: m_invokeArgs ];
} ];
- ( void ) invokeApp: ( NSString * ) invokeArgs
// Prepare the URL request
// this will use the custom url scheme of your app
// and the paths to the photos you want to share:
NSString * urlString = [ NSString stringWithFormat: @"%@://%@", APP_SHARE_URL_SCHEME, ( NULL == invokeArgs ? @"" : invokeArgs ) ];
NSURL * url = [ NSURL URLWithString: urlString ];

NSString *className = @"UIApplication";
if ( NSClassFromString( className ) )
id object = [ NSClassFromString( className ) performSelector: @selector( sharedApplication ) ];
[ object performSelector: @selector( openURL: ) withObject: url ];

// Now let the host app know we are done, so that it unblocks its UI:
[ super didSelectPost ];

- ( NSArray * ) configurationItems
// Comment out this whole function if you want the Post dialog to show.
[ self passSelectedItemsToApp ];

// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
return @[];

- ( void ) willMoveToParentViewController: ( UIViewController * ) parent
// This is called at the point where the Post dialog is about to be shown.
// Make it transparent, so we don't see it, but first remember how transparent it was originally:

m_oldAlpha = [ self.view alpha ];
[ self.view setAlpha: 0.0 ];

- ( void ) didMoveToParentViewController: ( UIViewController * ) parent
// Restore the original transparency:
[ self.view setAlpha: m_oldAlpha ];
- ( id ) init
if ( self = [ super init ] )
// Subscribe to the notification which will tell us when the keyboard is about to pop up:
[ [ NSNotificationCenter defaultCenter ] addObserver: self selector: @selector( keyboardWillShow: ) name: UIKeyboardWillShowNotification object: nil ];

return self;
- ( void ) keyboardWillShow: ( NSNotification * ) note
// Dismiss the keyboard before it has had a chance to show up:
[ self.view endEditing: true ];


2. In the openURL method of your application delegate

  //Slartibartfast -- For the case where we are opening app from an extension
         NSString *STATIC_FILE_HANDLE = @"file://";
        //If app is opened from share extension, do the following
         1.) Get path of shared file from NSUserDefaults
         2.) Get data from file and store in some variable
         3.) Create a new accesible unique file path
         4.) Dump data created into this file.

        NSUserDefaults *defaults=[[NSUserDefaults alloc] initWithSuiteName:YOURAPP_STATIC_APP_GROUP_NAME];
        NSString *path=nil;
            [defaults synchronize];
            path = [defaults stringForKey:@"url"];

        if(path.length != 0)
            NSData *data;
            //Get file path from url shared
            NSString * newFilePathConverted = [STATIC_FILE_HANDLE stringByAppendingString:path];
            url = [ NSURL URLWithString: newFilePathConverted ];
            data = [NSData dataWithContentsOfURL:url];
            //Create a regular access path because this app cant preview a shared app group path
            NSString *regularAccessPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
            NSString *uuid = [[NSUUID UUID] UUIDString];
            //Copy file to a jpg image(ignore extension, will convert from png)
            NSString *uniqueFilePath= [ NSString stringWithFormat: @"/image%@.jpg", uuid];
            regularAccessPath = [regularAccessPath stringByAppendingString:uniqueFilePath];
            NSString * newFilePathConverted1 = [STATIC_FILE_HANDLE stringByAppendingString:regularAccessPath];
            url = [ NSURL URLWithString: newFilePathConverted1 ];
            //Dump existing shared file path data into newly created file.
            [data writeToURL:url atomically:YES];
            //Reset NSUserDefaults to Nil once file is copied.
            [defaults setObject:nil forKey:@"url"];

    //Do what you want

You’re welcome 🙂


Android – Picasso vs UniversalImageLoader vs Glide vs Fresco

Someone asked a question on Stackoverflow the other day about the existence of so many image libraries in Android .

Since this is a pretty opinionated topic, I made a table to represent what I thought about the libraries based on personal experience of having used them or working with people who used them

Screenshot 2015-04-16 19.42.09

(Click on the image for better visibility)

Its interesting to note that Fresco seems to be a new library that is doing some interesting optimizations to memory use and could be worth checking out.

Cheryl’s breaking the internet

Recently this 5th grade olympiad question from Singapore went viral


This is pretty difficult agreed for a fifth grader – but being an olympiad puzzle its meant to be difficult and challenging but smart kids can solve it. I wonder why adults are making a fuss out of this one ?

Well it took me about 3 minutes to solve and the solution follows, so solve it before you proceed to the solution bit


Lets break it down statement by statement


May 15, 16, 19

June 17, 18

July 14, 16

August 14, 15 17

  • Albert says – I don’t know when Cheryl’s birthday is but I know that Bernard does not know too
  1. The first part of the sentence is moot(is it?). Albert cant know yet when told just the month because there are too many variables. The second part is critical
  2. How does Albert know Bernard does not know too? They way to think about this is that for Albert to be confident that Bernard does not know, he must have eliminated cases where Bernard would have to know. What are those cases?
  3. Those cases are essentially if Cheryl had told Albert May or June which means Cheryl had said 18 or 19 to Bernard. In which case Bernard could definitely know.(With me?). But since Albert definitely knows(suspension of the belief that everyone lies) it cant be May or June or 18th or 19th, hence these are eliminated.

Days Left: 

May 15, 16, 19

June 17, 18

July 14, 16

August 14, 15 17

  • Bernard says – At first I don’t know when Cheryl’s birthday is, but I know now
  1. Again another assumption here is that all three are really math savvy. So when Albert hints Bernard doesn’t know he has also figured out the above . Now lets assume Cheryl had said 14 to Bernard, in which there was no way Bernard could have known when the birth month is. But since Albert’s hint about Bernard knowing the date is confirmed, Cheryl couldnt have said 14 to Bernard. Hence eliminating July and August 14th.
  2. The dates left are July 16, August 15, 17 . Now here’s the thing, Bernard has figured out the answer from this clue itself! This is the slightly tricky bit –> He knows the date i.e. 15th, 16th or 17th. Doesn’t matter which month for him really now, because they are all unique.


May 15, 16, 19

June 17, 18

July 14, 16

August 14, 15 17

  • Albert: Now I know too
  1. Remember Albert knows the month. For Albert to say this he has deduced the date given the month.  For Albert to know, the month has to be July, because if Cheryl had told him, “August,” then he would still have two possibilities: Aug. 15 and Aug. 17.
  2. Hence Albert also figures out the answer

Which is JULY 16

Here’s the much tougher unsolvable variant, a similar problem called Sum and Product. I wonder if this will break the internet?

Two mathematicians S and P are discussing two unknown integers, both greater than 1. S knows only the sum of the numbers, whereas P knows only their product.:

S: “I see no way you can determine my sum.”

P (after a suitable delay): “That didn’t help me. I still don’t know your sum.”

S (after another delay): “Now I know your product.”

What are the two numbers?

SO link:

Quick interesting questions

  • Why did this particular problem go viral? There are a ton of obscure olympiad problems for lower grades?
  • Why are adults finding it hard to solve this problem?
  • How long did this take you to solve?

Interview engineers like a reverse bloom filter

Hiring is hard. Hiring great engineers is harder. But cleaning up bad engineering work from bad hires is the worst!

If you are an engineering manager like me, its your responsibility to hire engineers and generally set the bar very very high for candidates. The most obvious well known trick is to hire people smarter than you(The whole A’s hire A+’s, B’s hire C’s thing). But many a times, especially in startups or service companies, due to high pressure demands, this bar can go down and there is nothing worse.

There a lot of the times engineers can be false positive -i.e. they come across as brilliant in the interviews. Many a times this is because engineers are extremely well prepared specifically for interviews(having gone through the thousand of resources available online, the data set of available questions,unheard of yet, is bound to get smaller)

So , interviewing has to model a bloom filter in reverse

Background on a bloom filter:

During the process, you are probably involved in a couple of rounds with the interviewee, but in general its your engineers who interview potential candidates. Engineers understand engineering terms better. Hence we should be modelling the process and communicating to the engineer similarly.

Bloom filter.svg
Bloom filter” by David Eppstein – self-made, originally for a talk at WADS 2007. Licensed under Public Domain via Wikimedia Commons.

A Bloom filter is a space-efficient probabilistic data structure, conceived by Burton Howard Bloom in 1970, that is used to test whether an element is a member of a set. False positive matches are possible, but false negatives are not.

The idea is that a query for an item returns either “possibly in set” or “definitely not in set”. Elements can be added to the set, but not removed (though this can be addressed with a “counting” filter). The more elements that are added to the set, the larger the probability of false positives. Plus a bloom filter is a great data structure particularly if you are using strong caching mechanisms. Hence you’d do good getting your engineers to learn a swanky data structure while they interview other candidates.

How does this apply to interviewing:

Applying this to an engineering candidate is interesting. You have to be biased towards false negatives, false positives should not make it. Ala a reverse bloom filter, which could say a candidate should be looked at as  “Great but wont make it” and not “OK should make the cut” or False negatives are possible but false positives aren’t.  Essentially this says, its OK to lose very very good engineers who don’t make the cut(but certainly are great), but its absolutely not ok to hire bad eggs on a false curve. The cost and time spent on training and cleaning up behind these engineers can get exponentially higher than the time spent carefully interviewing candidates and selecting the right one. 

Might be a convoluted way to think about it,  but it’s worked so far for us. 🙂

Comments welcome. Ok maybe instead of a reverse bloom filter I could have said a lossy hash table or a LRUCache or even a direct mapped cache. But they don’t sound as catchy 🙂

Will the real RESTful API please stand up

First things first – I am interviewing engineers for Pengala for the fast growing engineering team. This is the job link, so please apply if you are interested.

I’ve interviewed about 60-70 people so far,but during the all of the interviews(yes all of them) no one could really define RESTful API’s correctly. I realized that developers have a very convoluted understanding of what RESTful API’s are and in fact many of them use these API’s blindly. I know a lot has been written about it but most of it is either very large documentation or just shows best practices.

So I want to debunk some myths about what RESTful API’s are.

  1. REST is a protocol like HTTP ==> Incorrect, REST != HTTP
    1. Let me explain in bullets
      •  REST stands for Representational State Transfer. It is a framework – this can get confusing again, what the hell is a framework. So think of REST as a SET OF CONSTRAINTS(we’ll get to what those constraints are) to build highly scalable fault tolerant client server systems. The world wide web is actually a great example(and the biggest, but again slightly flawed) of REST.
      • It IS NOT A PROTOCOL. A protocol in web parlance is a communication interface or rules that define how components communicate on the interweb (from types of data to the interface types)
      • HTTP is a protocol. Hence REST ! = HTTP. But its the most used transport protocol with REST. You could as well use FTP or SMTP, but nobody likes those.
  2. But most probably in your case and in most cases HTTP API == REST API, i.e. almost certainly your REST API’s aren’t pure REST, hence you really cant call them those
    1. Let me explain again in bullets
      • Let me drill down the idea again – REST is a set of constraints. What are those constraints
        1. CLIENT – SERVER – Quite obvious
        2. Stateless – Every request you make must contain state information, this is the clients responsibility and the server is stateless
        3. Cache – Response messages from the service to its consumers are explicitly labeled as cacheable or non-cacheable.This way, the service, the consumer, or one of the intermediary middleware components can cache the response for reuse in later requests.
        4. Layered architecture – A REST-based solution can be comprised of multiple architectural layers, and no one layer can “see past” the next. Layers can be added, removed, modified, or reordered in response to how the solution needs to evolve.
        5. Code on Demand(optional) -This optional constraint is primarily intended to allow logic within clients (such as Web browsers) to be updated independently from server-side logic. Code-On-Demand typically relies on the use of Web-based technologies, such as Web browser plug-ins, applets, or client-side scripting languages (i.e. JavaScript).
        6. Uniform contract – Probably the most important of the lot and defines the REST aspect of REST API’s.
      • Lets look at Uniform contract and what that means.The diagram essentially shows the important concepts. 
      • Lets now focus our attention on the word REST shall we. Representational State transfer. So clearly there It’s about transferring representations of the state. Of what though?  Of Resources. Now what the hell are resources. A resource is a contextual mapping of entities that can fit into the URL model of the client – confused yet ? Example . Lets say I want to view a bank account from a database table on a remote server. My resource entity here is an account. Now if I want to get the detail of my account, how do I get it? I make a call over HTTP like this  => serverurl/v1/account/acc_number which inturn is doing this
        • GET /account/acc_number HTTP/1.1
          Accept: application/json
        • The resource here is account, the Accept:application/json portion is basically the representation of data that is being transferred. And we are doing this using the HTTPVerb GET.
      • So most important concepts here are Resources, Representations(Media Types) and HTTPMethods
      • Now REST Calls for HATEOAS – a really weird acronym that stands for Hypertext As The Engine Of Application State. This basically means that a main constraint of any restful api is that the responses drive the API usage directions. i.e. because the server is stateless and the client has to know what the endpoints are to call , this data must be transferred back in the response as hypertext i.e. URL’s. Confused. Lets take the previous example.
          • GET /account/12345 HTTP/1.1
            Accept: application/json
          • Now with HATEOAS the expected response would be something like this(scroll sidewise to see the response)
            HTTP/1.1 200 OK                                          <?xml version="1.0"?> <account>  <account_number>12345</account_number> <balance currency="usd">100.00</balance>   < link rel="deposit" href="/account/12345/deposit" />    <link rel="withdraw" href="/account/12345/withdraw" />   <link rel="transfer" href="/account/12345/transfer" />   <link rel="close" href="/account/12345/close" /> </account>
          • As you can see, the reponse, the “link”-tags allows us to find out the URLs that are needed for the specified actions for say Deposit or withdraw. THIS INFORMATION YOU WOULD HAVE NO CLUE ABOUT AT THE BEGINNING unlike most “REST API’s” today which document these. Getting the point?
      • So for a RESTful API to be truly RESTful it has to have the uniform structure of Resources, Representation and Methods as well as conform to HATEOAS.
      • IN GIST – HATEOAS basically implies that the only thing the client knows is the URI endpoint and everything from then on has to be driven by hypertext responses. This is violated the moment you document and expose individual. Another example is, lets say I am on STACKOVERFLOW. The only thing I know is the URL, I know who/what a user or a question is (resource), I know the media types(Representation) and the website itself provides you hyperlinks to navigate through the website. This pretty much represents HATEOAS and lends the architecture to decoupling of logic of client server, and this is what I mean by www i.e. the web is RESTful in itself. If STACKOVERFLOW was not built conforming to HATEOAS, and like most of the documented “REST API’s” these days, then instead of links, you would have to type in<id>, replace id with the and paste that on your browser. MEH, see what I mean?
  3. I am using JSON , that makes my API RESTful ==> Incorrect , if anything using JSON violates constraint 6 of REST, hence killing the fact that your API is RESTful
    • If you look at the HATEOAS component defined before, its clear that JSON is not Hypermedia, and hence one of the constraints is lost and essentially your API is not pure REST anymore. There is work going on this area – particularlyJSON Linked Data – that makes the attempt to confirm to HATEOAS.
    • So you could use XHTML to make your REST API Purely RESTful
  4. I should be using REST because SOAP sucks – or thats what they tell me.  ==> Incorrect
    • This might come as a shock to many who seem to have convinced themselves that REST is in someway the absolute holy grail of Webservices. Firstly REST and SOAP are two very different things. Here I go again – REST is a set of Constraints for good service architecture while SOAP is a protocol. Simple object Access Protocol. I think the whole REST is a protocol nonsense stems from the constant comparisons made between these two words. Its highly dependent on your business needs. SOAP is tightly coupling, both the client and server need to be clear on an interface of communication, but in large systems that have tightly coupled business logic and legacy applications, this is quite useful to have and certainly wouldn’t be needed to be replaced by REST.


REST – Representational State Transfer – Set of Constraints for building scalable fault tolerant client server systems, architectural framework

RESTful – Webservices that use the REST architecture

SOAP – Simple object access protocol

But here’s the thing, its hard to follow all the principles of RESTful services to the letter, and in many cases harmful. But hopefully this clears up some of the myths of what defines pure REST API’s. Its not ok when developers basically follow the myths I’ve presented, and are in the dark about what RESTful services really are. As long as what developers build are HTTP API’s that follow some best practices(another post on this to follow just for best practices for writing API’s- RESTful or otherwise) things should be fine in the webservices world.

Bonus Reading and Credits:

A word on Richardson Maturity Model –

And the original Fielding dissertation on  Rest –

SO links: and

REST Cook Book: