I'm trying to use Google Drive in my iOS app. It authenticates and browses ok, but when I try to upload a file, I get the following error:
*** Assertion failure in -[GTLService uploadFetcherWithRequest:fetcherService:params:](), /google-api-objectivec-client-read-only/Source/Objects/GTLService.m:565
Here's my relevant code:
GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:fileContent MIMEType:#"application/pdf"];
GTLDriveFile *file = [[GTLDriveFile alloc] init];
file.title = #"test.pdf";
GTLQueryDrive *query = [GTLQueryDrive queryForFilesInsertWithObject:file uploadParameters:uploadParameters];
[self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFile *updatedFile,
NSError *error) {
NSLog(#"Done");
}];
Has anyone run into this problem? Obviously I'm missing something somewhere in the setup I guess but I have no idea what.
Add -ObjC -all_load to the Other Linker Flags setting in the application project's Build Settings.
check above step in https://developers.google.com/drive/quickstart-ios
I browsed through the source and the corresponding line is:
GTL_ASSERT(uploadClass != nil, #"GTMHTTPUploadFetcher needed");
A search for that on stackoverflow led to this answer:
It indicates that the class GTMHTTPUploadFetcher is not linked in to your application.
The class may be missing due to the class file not being linked in the debug or release build target, or due to the preprocessor define GDATA_INCLUDE_YOUTUBE_SERVICE not being set, as described under "Removing Unneeded Code" at http://code.google.com/p/gdata-objectivec-client/wiki/BuildingTheLibrary
Related
I am working on google client Api V3 for uploading files from my IOS Application.
The Scopes I have used are
NSArray *scopes = [NSArray arrayWithObjects:kGTLAuthScopeDrive,kGTLAuthScopeDriveFile,kGTLAuthScopeDriveAppdata,kGTLAuthScopeDriveMetadata, nil];
The code I used for uploading a new file is
GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:data MIMEType:file.mimeType];
GTLQuery * query = [GTLQueryDrive queryForFilesCreateWithObject:metadata uploadParameters:uploadParameters];
GTLServiceTicket *uploadTicket=[self.gogService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFile *updatedFile,
NSError *error) {
if (error == nil) {
NSLog(#"File WebContent Link %#", [updatedFile webViewLink]);
}
else {
NSLog(#"An error occurred: %#", [error localizedDescription]);
}
}];
[uploadTicket setUploadProgressBlock:^(GTLServiceTicket *ticket, unsigned long long totalBytesWritten, unsigned long long totalBytesExpectedToWrite)
{
progressBar.progress=(1.0*totalBytesWritten/(1.0*totalBytesExpectedToWrite)) ;
NSLog(#"%llu",totalBytesWritten);
NSLog(#"%llu",totalBytesExpectedToWrite);
}];
The problem is web content link is null and want it in response to store it in my database because my web App will use this link to open that file.
Previous version of google drive api was returning web content link.
How can I get Web Content Link?
Check this documentation: Migrate to Google Drive API v3. Be noted that full resources are no longer returned by default. Use the fields query parameter to request specific fields to be returned. If left unspecified only a subset of commonly used fields are return. You may check this sample for reference.
I am asking a general question, Can i fetch all photos from the Google Drive without Downloading process.I am using a Google Drive SDK and i am very stuck for finding the solution.Any one have experience in google drive sdk. Please share your experience.Thanks for any help.
I want only fetch the Google Drive Photos not download in our application.
You can use Drive's query parameters while using the code snippet on the Querying for Files section of the documentation
I checked the Supported MIME Type section, and you can set the q attribute as
NSString *search = #"mimeType = 'application/vnd.google-apps.photo'";
GTLServiceDrive *drive = ...;
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
query.q = search;
[drive executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFileList *fileList,
NSError *error) {
if (error == nil) {
NSLog(#"Have results");
// Iterate over fileList.files array
} else {
NSLog(#"An error occurred: %#", error);
}
}];
In my current application, I am trying to upload a .text file to google drive using Google SDK for iOS. But the issue is every time I got the error message in my Log as Insufficient Permission, so If anyone have faced this or have an idea on this type of error kindly help me.
Here is my code,
GTLDriveFile *file = [GTLDriveFile object];
file.descriptionProperty = #"Uploaded from the iOS app.";
file.mimeType = #"text/*";
file.name=#"MyTextFile";
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"myTestFile" ofType:#"txt"];
GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithFileURL:[NSURL URLWithString:filePath] MIMEType:file.mimeType];
GTLQueryDrive *query = [GTLQueryDrive queryForFilesCreateWithObject:file uploadParameters:uploadParameters];
[self.service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
}else{
}
}];
Log print when this action is performed,
unexpected response data (uploading to the wrong URL?)
{"error":{"code":403,"message":"Insufficient Permission","data":[{"domain":"global","reason":"insufficientPermissions","message":"Insufficient Permission"}]},"id":"gtl_3"}
Premature failure: upload-status:"final" location:(null)
I solve this problem
First Step
change your scope to [kGTLAuthScopeDriveFile]
but after first step, i got a same 403 error
because my APP in my phone have scope [kGTLAuthScopeDriveMetadataReadonly]
Second Step
reset my application or build in another simulator
I think first auth key chain using scope readonly was existed so doesn't write file to google drive
after change scope and re-auth then it works
if you change kKeychainItemName's value to another then could re-auth again with new scope
google says in Quickstart tutorial
// If modifying these scopes, delete your previously saved credentials by
// resetting the iOS simulator or uninstall the app.
// private let scopes = [kGTLAuthScopeDriveFile]
I have a GTLServiceTicket object aimed to facilitate me to upload files. It is defined earlier in my code as
GTLServiceTicket *_uploadFileTicket;
And called using
NSString *mimeType = [self MIMETypeForFilename:filename
defaultMIMEType:#"video/mp4"];
GTLUploadParameters *uploadParameters =
[GTLUploadParameters uploadParametersWithFileHandle:fileHandle
MIMEType:mimeType];
uploadParameters.uploadLocationURL = locationURL;
GTLQueryYouTube *query = [GTLQueryYouTube queryForVideosInsertWithObject:video
part:#"snippet,status"
uploadParameters:uploadParameters];
GTLServiceYouTube *service = self.youTubeService;
_uploadFileTicket = [service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
GTLYouTubeVideo *uploadedVideo,
NSError *error) {
// Callback
NSLog(#"Here!");
//Other uploading file stuff
This used to be working really well. Now the "Here" doesnt even get called. So whatever is happening, its not running that GTLServiceTicket object at all. Its only until very recently that its stopped working. Within that time frame I've implemented two new features:
Google plus sign in
Youtube video searches and gets (on a different view controller).
And heres what I can confirm about my problem:
No error is passed at all, I have an if statement to catch any errors and I cant even get that. Its like its a dud command.
The file location/URL are correct
So my questions are:
How would I go about further investigating this? As in, where would I look within the frameworks to find out where it is going wrong? What trail is this command following (I have NO idea and have tried to find it).
Does anybody have any ideas?
Thanks!
Actually i integrated google drive sdk with my ios app. I can able to retrieve/upload the files in google drive through google drive ios sdk. But the retrieving files list from specified parent folder taking so much time.
Here the steps and the code which was i am using.
First am getting the children's of the specified parent folder then am getting the GTLDriveChildReference of each child then
then am querying with the child reference identifier.
This is huge process for me. Also it request google server each time. Any better way there to just pass the parent folder id in a query and pulling the files from that parent folder.
-(void)getFileListFromSpecifiedParentFolder {
GTLQueryDrive *query2 = [GTLQueryDrive queryForChildrenListWithFolderId:<some_id or root>];
query2.maxResults = 1000;
// queryTicket can be used to track the status of the request.
[self.driveService executeQuery:query2
completionHandler:^(GTLServiceTicket *ticket,
GTLDriveChildList *children, NSError *error) {
NSLog(#"\nGoogle Drive: file count in the folder: %d", children.items.count);
//incase there is no files under this folder then we can avoid the fetching process
if (!children.items.count) {
return ;
}
if (error == nil) {
for (GTLDriveChildReference *child in children) {
GTLQuery *query = [GTLQueryDrive queryForFilesGetWithFileId:child.identifier];
// queryTicket can be used to track the status of the request.
[self.driveService executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFile *file,
NSError *error) {
NSLog(#"\nfile name = %#", file.originalFilename);
}];
}
}
}];
}
Any help that might be appreciated.
I've been using the following code (which only requires one query rather than multiple queries):
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
query.q = [NSString stringWithFormat:#"'%#' IN parents", <the folderID>];
[self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFileList *files,
NSError *error) {
...
}];
Seems to be working well thus far.
Try combining queries in a batch query, like
GTLBatchQuery *batchQuery = [GTLBatchQuery batchQuery];
for (GTLDriveChildReference *child in children) {
GTLQuery *query = [GTLQueryDrive queryForFilesGetWithFileId:child.identifier];
query.completionBlock = ^(GTLServiceTicket *ticket, GTLDriveFile *file, NSError *error) {
NSLog(#"error=%#, file name = %#", error, file.title);
};
[batchQuery addQuery:query];
}
[driveService executeQuery:batchQuery completionHandler:...]
If automatic fetching of result pages is enabled (service.shouldFetchNextPages = YES) then try to set the maxResults property of queries to avoid the need for the library to make multiple fetches. For example, if there are 100 or fewer results for a query, a maxResults value of 100 will retrieve them with a single fetch.
Requests for partial responses are also a bit faster and use much less memory, particularly for large results.
Look at http logs for a better idea of the response sizes for your queries.