How do I upload files to Google Cloud Storage in Objective-C/iOS? -
i've been looking documentation on how upload files 'bucket' in google cloud storage ios app, can't find @ on subject. no documentations, no tutorials, no example projects. blind? trying find way app-users upload file "public bucket", , url in return. can find chunks of http-protocols or json etc, , have no idea how use that, there's no reference either. feels author of documentations expects me know already. i've found osx-example codes, without documentation, , i've been trying read code have provided, no luck.
what i'm looking this: (this code made up. it's want. noticed google used prefix gtl* classes)
nsdata *datatoupload = ... ; //or uiimage or movie-format or whatever nsurl *destination; gtlstorageuploader *uploader = [gtlstorageuploader alloc]initwithbucket:@"mybucket" withhashorkeyorsomething:@"a1b2c3hashkeyorwhatever"]; destination = [uploader uploaddata:datatoupload];//inbackground etc..
it's easier when using parse.com, there's not enough storage space app there, need able upload data files google cloud storage. how?
i did work. wasn't pretty, though. it's quite long time ago now, can't remember logic etc, i'll post made work, , change id-stuff. hope helps, , sorry didn't remember write when found out , fresh in mind. don't have time @ moment.
an important note: had change lot of permissions on bucket , on users/authorized on googlecloudstorage make work. tried many different combinations, think stuff did:
- on each bucket: "allow upload/delete/edit etc".
- on auth entire cloudstorage: "allow entities accesstoken access cloudstorage.
- allow www.yourappengineurl.com request such accesstoken.
this felt wrong, , still does. if gets hold of accesstoken, can whatever want long accesstoken valid. like.. delete files. way make work. of course, authorized users request accesstoken our appengine, still.. meh. i'm no security-guru, , fun project, let go. code.
when uploading:
gtlservicestorage *serv = [[gtlservicestorage alloc] init]; serv.additionalhttpheaders = [nsdictionary dictionarywithobjectsandkeys: @"123123123", @"x-goog-project-id", @"application/json-rpc", @"content-type", @"application/json-rpc", @"accept", nil]; gtlstorageobjectaccesscontrol *objaccesscontrol = [gtlstorageobjectaccesscontrol new]; objaccesscontrol.entity = @"project-owners-123456"; //some value control panel on cloudstorage or something. or apps.. or appengine, not sure. //probably connected accesstoken appengine requests , sends users. objaccesscontrol.role = @"owner"; gtlstorageobjectaccesscontrol *objaccesscontrol2 = [gtlstorageobjectaccesscontrol new]; objaccesscontrol2.entity = @"allusers"; objaccesscontrol2.role = @"reader"; //don't remember why need both. or do. hey ho. //it looks like.. can read. authorized accesstoken-people can write? probably. gtlstoragebucket *bucket = [[gtlstoragebucket alloc] init]; bucket.name = @"my_bucket"; nserror *err; nsfilehandle *filehandle = [nsfilehandle mylocalfileurlithink error:&err]; if(err) { nslog(@"some error here"); } gtluploadparameters *params = [gtluploadparameters uploadparameterswithfilehandle:filehandle mimetype:@"video/mp4 (or else)"]; gtlstorageobject *storageobject = [[gtlstorageobject alloc] init]; storageobject.acl = @[objaccesscontrol, objaccesscontrol2]; nsstring *key = [nsstring stringwithformat:@"filename.mp4"]; // should unique.. url cloud.com/my_bucket/filename.mp4 //you can generate unique putting user's userid , timestamp datetime right now. //this user never upload 2 things within second. storageobject.name = key;
after point in code magic i'm not gonna post. ask , receive accesstoken use on googlecloudstorage our own api. don't remember or how got token begin with, believe backend (appengine) had request cloudstorage-thing, using pretty standard call. and, said in beginning, changed settings on cloudstorage making our appengine entity allowed request token. or something.. token has lifecycle of like.. 15 minutes or so.. don't know, it's provided google-default-thing. might later if of need it.
nsstring *receivedaccesstoken = @"abc123"; //received cloudstorage via appengine. nsstring *accesstoken = @"bearer %@", receivedaccesstoken" //(pseudo) because needed "bearer " first. don't know why, or how found out.. [serv setadditionalhttpheaders:[nsdictionary dictionarywithobject:accesstoken forkey:@"authorization"]]; //upload-magic: gtlquerystorage *query = [gtlquerystorage queryforobjectsinsertwithobject:storageobject bucket:bucket.name uploadparameters:params]; gtlserviceticket *t = [serv executequery:query completionhandler:^(gtlserviceticket *ticket, id object, nserror *error) { //handle error first. nslog(@"success!"); dispatch_async(dispatch_get_main_queue(), ^{ actualurl = [nsstring stringwithformat:@"%@%@", yourfullbucketurl /*( e.g www.googlecloud.com/my_bucket)*/, key /*file.mp4*/]; }); }];
and can track progress of upload after block, ticket-object (like, t.uploadprogressblock = ...
).
this code has been edited quite bit stack-purposes now, might have screwed something, doesn't work this. read it, , try understand how works. luck. if have option, stay amazon or else, not fun work with. worst documentation ever. also, amazon's s3 uploads/downloads faster googlecloudstorage. regret changing amazon google. amazon had better api too, 1 in question.
here's code used appengine request accesstoken:
private googlecredential getgooglecredential(string scope) throws generalsecurityexception, ioexception { jsonfactory json_factory = jacksonfactory.getdefaultinstance(); httptransport httptransport = googlenethttptransport.newtrustedtransport(); googlecredential credential = new googlecredential.builder() .settransport(httptransport) .setjsonfactory(json_factory) .setserviceaccountid(constants.service_account_email) .setserviceaccountprivatekeyfromp12file(new file(constants.cloud_storage_key)) .setserviceaccountscopes(collections.singleton(scope)) .build(); return credential; }
the parameter "scope" sent in method either https://www.googleapis.com/auth/devstorage.read_only
or https://www.googleapis.com/auth/devstorage.read_write
the method returns googlecredential-object, on can call googlecredential.refreshtoken()
. believe call made token. i'm not sure though.
the constants (email , key) stuff need set , auth-page on google cloud storage, think.
this documentation should cover of (it looks more documented did then, think): https://cloud.google.com/storage/docs/authentication