I am very new to IOS development, I am developing an app in which I want to download a file from Google Drive (pdf,doxc,doc and xlxs) and which will be sent to sent it to our server.
First I have installed it in pod file by using
pod 'GoogleAPIClient/Drive', '~> 1.0.2'
pod 'GTMOAuth2', '~> 1.1.0'
Second I created a project in Google Developer Console with bundle id and got client id, I have saved it into my project.
When user clicks select file button
-(IBAction)onclickfileFromDrive:(id)sender
{
self.service = [[GTLServiceDrive alloc] init];
self.service.authorizer = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName clientID:kClientID clientSecret:nil];
NSLog(#"service reply%hhd",self.service.authorizer.canAuthorize);
if (!self.service.authorizer.canAuthorize)
{
[self presentViewController:[self createAuthController] animated:YES completion:nil];
}
else
{
[self fetchFiles];
}
}
- (GTMOAuth2ViewControllerTouch *)createAuthController
{
GTMOAuth2ViewControllerTouch *authController;
NSArray *scopes = [NSArray arrayWithObjects:kGTLAuthScopeDrive, nil];
authController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:[scopes componentsJoinedByString:#" "]
clientID:kClientID
clientSecret:nil
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
return authController;
}
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)authResult error:(NSError *)error
{
if (error != nil)
{
[self showAlert:#"Authentication Error" message:error.localizedDescription];
self.service.authorizer = nil;
}
else
{
self.service.authorizer = authResult;
[self dismissViewControllerAnimated:YES completion:nil];
}
self.service.authorizer = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName clientID:kClientID clientSecret:nil];
NSLog(#"service reply%hhd",self.service.authorizer.canAuthorize);
if (self.service.authorizer.canAuthorize)
{
[self fetchFiles];
}
}
The process of login is working fine here I am getting access token and refresh token
while I am trying to download a file
- (void)fetchFiles
{
GTLQueryDrive *query =[GTLQueryDrive queryForFilesList];
query.q = #"mimeType ='application/pdf' or mimeType ='text/plain' or mimeType ='application/msword' or mimeType ='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' or mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'";
[self.service executeQuery:query delegate:self didFinishSelector:#selector(displayResultWithTicket:finishedWithObject:error:)];
}
- (void)displayResultWithTicket:(GTLServiceTicket *)ticket finishedWithObject:(GTLDriveFileList *)response error:(NSError *)error
{
if (error == nil)
{
NSMutableString *filesString = [[NSMutableString alloc] init];
if (response.files.count > 0)
{
for (GTLDriveFile *file in response.files)
{
[filesString appendFormat:#"%# (%#)\n", file.name, file.identifier];
NSString *url = [NSString stringWithFormat:#"https://www.googleapis.com/drive/v3/files/%#?key=%#", file.identifier,kClientID];
GTMSessionFetcher *fetcher = [_service.fetcherService fetcherWithURLString:url];
[fetcher beginFetchWithCompletionHandler:^(NSData *datav, NSError *error)
{
if (error == nil)
{
NSLog(#" file web link%#",file.webViewLink);
NSLog(#"file extension%#",file.fileExtension);
NSLog(#"Retrieved file content%#",datav);
NSString *prefixString = #"EMR File";
NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString] ;
NSString *uniqueFileName = [NSString stringWithFormat:#"%#_%#", prefixString, guid];
NSString *filePath = [[NSString alloc]init];
/***************** save the file in document directory ***********************/
if (datav!=nil)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//Get the docs directory
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *folderPath = [documentsDirectoryPath stringByAppendingPathComponent:#"emrFiles"]; // subDirectory
if (![[NSFileManager defaultManager] fileExistsAtPath:folderPath])
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:NO attributes:nil error:nil];
//Add the FileName to FilePath
filePath = [folderPath stringByAppendingPathComponent:[uniqueFileName stringByAppendingFormat:#".%#",file.fileExtension]];
//Write the file to documents directory
[datav writeToFile:filePath atomically:YES];
}
}
else
{
NSLog(#"An error occurred: %#", error.localizedDescription);
}
}];
}
}
else
{
[filesString appendString:#"No files found."];
}
}
else
{
[self showAlert:#"Error" message:error.localizedDescription];
}
}
the file details like
NSLog(#" file web link%#",file.webViewLink);
NSLog(#"file extension%#",file.fileExtension);
file.fileExtension
These are getting null in all the time
However I am getting value for
file.name
file.identifier
Finally if I try to download a file using this url
NSString *url = [NSString stringWithFormat:#"https://www.googleapis.com/drive/v3/files/%#?key=%#", file.identifier,kClientID];
and
NSString *url = [NSString stringWithFormat:#"https://www.googleapis.com/drive/v3/files/%#?key=My API key from google console",
myfile.identifier];
I am getting nsdata very small content
Printing description of datav:
<7b0a2022 6b696e64 223a2022 64726976 65236669 6c65222c 0a202269
64223a20 22304236 6a6e576c 46497868 434f566e 6c586546 4a496344
526d596d 68694e44 6c735432 557a516b 7057566c 70716431 5246222c
0a20226e 616d6522 3a202253 41544859 412e646f 6378222c 0a20226d
696d6554 79706522 3a202261 70706c69 63617469 6f6e2f76 6e642e6f
70656e78 6d6c666f 726d6174 732d6f66 66696365 646f6375 6d656e74
2e776f72 6470726f 63657373 696e676d 6c2e646f 63756d65 6e74220a 7d0a>
Because of getting null value of file extension I tried with giving static extension and saved it in directory and try to view it and I get this error
“ File_B85DABFF-BCA5-4B5E-8FDC-59D2907F0509-1053-000003B0E6E4C9A9.docx” can’t be opened for some reason.
I don't know that where I am lacking I have searched more but could not help please any one help me on this
thanks in advance
Related
I am using the Google Drive API. When I use the demo to get the file list I think this app run multi thread. Now I want get file list when method succeeds.
- (void)fetchFiles {
self.output.text = #"Getting files...";
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
//query.pageSize = 10; /* Total number of files to get at once But useful only when there are more than hundreds of file to get once.*/
query.fields = #"nextPageToken, files(id, name)";
[self.service executeQuery:query delegate:self didFinishSelector:#selector(displayResultWithTicket:finishedWithObject:error:)];
}
link : https://developers.google.com/drive/ios/quickstart
Your can try it.
#property (nonatomic, copy) void(^blockHandler)(id data);
// get list file
- (void)listFiles:(NSString *)fileId complete:(void(^)(id data))completion {
self.blockHandler = completion;
GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
query.fields = #"nextPageToken, files(id, name, thumbnailLink, webViewLink)";
query.pageSize = 1000;
query.q = [NSString stringWithFormat:#"'%#' In parents and trashed=false",fileId];
[self.service executeQuery:query
delegate:self
didFinishSelector:#selector(displayResultWithTicket:finishedWithObject:error:)];
}
- (void)displayResultWithTicket:(GTLRServiceTicket *)ticket
finishedWithObject:(GTLRDrive_FileList *)result
error:(NSError *)error {
if (error == nil) {
NSMutableString *output = [[NSMutableString alloc] init];
if (result.files.count > 0) {
[output appendString:#"Files:\n"];
for (GTLRDrive_File *file in result.files) {
itemGG *temp = [[itemGG alloc] initWithName:file.name linkThumb:file.thumbnailLink fileID:file.identifier];
[self.lstItem addObject:temp];
[output appendFormat:#"%# (%#)\n", file.name, file.identifier];
}
} else {
[output appendString:#"No files found."];
}
NSLog(#"%#", output);
} else {
NSLog(#"Error getting presentation data: %#\n", error.localizedDescription);
}
if (self.blockHandler) {
self.blockHandler([[NSArray alloc] initWithArray:self.lstItem]);
}
}
__weak typeof(self) w = self;
[self.cloud listFiles:#"root" complete:^(id data) {
w.tableData = data;
[w.myCollection reloadData];
}];
For my pubnub chat app, I am storing some messages locally to keep it from using tons of wifi/data. It seems to work fine, but sometimes the last message is duplicated. Here is my saving,loading,reloading code.
#pragma mark - PubNub manager methods
- (NSString *)parseMessage:(id)message
{
if ([message isKindOfClass:[NSDictionary class]]) {
NSDictionary *messageAsDict = message;
if ([[messageAsDict objectForKey:#"text"] isKindOfClass:[NSString class]]) {
NSString *messageString = [messageAsDict objectForKey:#"text"];
if (messageString || messageString.length > 0) {
return messageString;
} else {
return #"Unable To Parse Message";
}
} else {
return #"Unable To Parse Message";
}
} else if ([message isKindOfClass:[NSString class]]) {
NSString *messageString = message;
if (messageString.length > 0) {
return messageString;
} else {
return #"Unable To Parse Message";
}
} else {
return #"Unable To Parse Message";
}
}
- (void)saveObjects
{
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *messagesDirectoryPath = [docDir stringByAppendingPathComponent:#"Messaging"];
if (![[NSFileManager defaultManager] fileExistsAtPath:messagesDirectoryPath]) {
[[NSFileManager defaultManager] createDirectoryAtPath:messagesDirectoryPath withIntermediateDirectories:YES attributes:nil error:&error];
}
NSString *messagesPath = [messagesDirectoryPath stringByAppendingPathComponent:messageFile];
NSString *timeTokenPath = [messagesDirectoryPath stringByAppendingPathComponent:timeTokenFile];
NSString *timeTokenString = [NSString stringWithFormat:#"%ld", (long)lastTimeToken];
[messagesArray writeToFile:messagesPath atomically:YES];
[timeTokenString writeToFile:timeTokenPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
}
- (void)loadObjects
{
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *messagesDirectoryPath = [docDir stringByAppendingPathComponent:#"Messaging"];
NSString *messagesPath = [messagesDirectoryPath stringByAppendingPathComponent:messageFile];
NSString *timeTokenPath = [messagesDirectoryPath stringByAppendingPathComponent:timeTokenFile];
messagesArray = [NSMutableArray arrayWithContentsOfFile:messagesPath];
if (!messagesArray) {
messagesArray = [[NSMutableArray alloc] init];
[self saveObjects];
}
NSString *timeTokenString = [NSString stringWithContentsOfFile:timeTokenPath encoding:NSUTF8StringEncoding error:&error];
if (![timeTokenString isEqualToString:#""]) {
lastTimeToken = [timeTokenString integerValue];
} else {
lastTimeToken = [self currentTimeToken];
[self saveObjects];
}
}
- (void)reloadMessages
{
messagesArray = [[NSMutableArray alloc] init];
//Get all the chats you missed
[self.pnClient historyForChannel:kCHAT_CHANNEL withCompletion:^(PNHistoryResult *result, PNErrorStatus *status) {
// Check whether request successfully completed or not.
if (!status.isError) {
// Handle downloaded history using:
// result.data.start - oldest message time stamp in response
// result.data.end - newest message time stamp in response
// result.data.messages - list of messages
// Get messages
for (id message in result.data.messages) {
[messagesArray addObject:[self parseMessage:message]];
}
// Set timetoken
lastTimeToken = [self parsePNTimeToken:result.data.end];
// Save stuff
[self saveObjects];
dispatch_async(dispatch_get_main_queue(), ^{
[self.messagesTable reloadData];
[self scrollToBottom];
});
} else {
// Request processing failed.
UIAlertController *errorController = [UIAlertController alertControllerWithTitle:#"Error" message:#"Could not recieve messages" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *retryAction = [UIAlertAction actionWithTitle:#"Retry" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[status retry];
}];
[errorController addAction:cancelAction];
[errorController addAction:retryAction];
[self presentViewController:errorController animated:YES completion:nil];
}
}];
}
- (void)addMessage:(PNMessageResult *)message
{
[messagesArray addObject:[self parseMessage:message.data.message]];
lastTimeToken = [message.data.timetoken integerValue] + 1;
[self saveObjects];
}
- (NSInteger)parsePNTimeToken:(NSNumber *)timeToken
{
return trunc([timeToken integerValue] / pow(10, 7));
}
- (NSInteger)currentTimeToken
{
return [[NSDate date] timeIntervalSince1970];
}
- (void)updateLostMessages
{
[self.pnClient historyForChannel:kCHAT_CHANNEL start:[NSNumber numberWithInteger:lastTimeToken] end:[NSNumber numberWithInteger:[self currentTimeToken]] limit:NSIntegerMax withCompletion:^(PNHistoryResult *result, PNErrorStatus *status) {
NSArray *tempResultArray = result.data.messages;
for (id message in tempResultArray) {
[messagesArray addObject:[self parseMessage:message]];
NSLog(#"%#", [self parseMessage:message]);
}
lastTimeToken = [self currentTimeToken] + 1;
[self saveObjects];
[self loadObjects];
dispatch_async(dispatch_get_main_queue(), ^{
[self.messagesTable reloadData];
[self scrollToBottom];
});
}];
}
These methods are pretty straightforward. the parseMessage: one takes a message from whatever and parses the text to be displayed. The saveObjects saves the timeToken and the messages to the disk, and load loads them. The timetoken methods just convert PN timetokens to a less precision format and get the current time token. The updateLostMessages gets all messages from the last messages timetoken to current, and to not get all the messages.
In viewDidLoad I call [self loadObjects] and then [self updateLostMessages] problem is that messages are duplicating! Help appreciated. Also, sorry for long code.
Haha, silly me. I just forgot a + 1 in the reload method. Well, for anyone who wants to use this code to locally store messages instead of getting all of them, here you go. This code stores a timetoken of the last message (+1), and gets all messages from x time token to now.
Here is a function of progressbar. In the sdk v1 I can use "S3Objectsummary" to know the summary of the the file, but in the sdk v2 i can not found the "S3Objectsummary".
Which one is the similar one in the v2? If any one can show an example that will be great.
Also, i have the same question with
S3GetObjectRequest/S3GetObjectResponse/S3PutObjectRequest/AmazonClientException
Code is in the sdk ios v1:
-(AmazonS3Client *)s3{
[self validateCredentials];
return s3;}
-(void)validateCredentials{
NSLog(#"validating credentials.");
if (s3 == nil) {
[self clearCredentials];
s3 = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
}
}
-(void)setProgressBar{
[delegate setProgressStatus:progPercent];
}
-(void)downloadPlists{
#try {
NSArray *Plists = [[self s3] listObjectsInBucket:#"~~~~"];
float numfile = 1;
float totalfiles = [Plists count];
for (S3ObjectSummary *file in Plists) {
float percent = numfile/totalfiles;
progPercent = [NSNumber numberWithFloat:percent];
[self performSelectorOnMainThread:#selector(setProgressBar) withObject:progPercent waitUntilDone:YES];
numfile++;
NSString *key = [file key];
NSLog(#"key: %#", key);
if ([key rangeOfString:#".plist"].location != NSNotFound) {
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistFilePath = [NSString stringWithFormat:#"%#/Plists/%#",docDir, key];
NSLog(#"plistFilePath: %#", plistFilePath);
S3GetObjectRequest *plist = [[S3GetObjectRequest alloc] initWithKey:key withBucket:#"~~~~~"];
S3GetObjectResponse *getObjectResponse = [[self s3] getObject:plist];
NSData *data2 = [NSData dataWithData: getObjectResponse.body];
NSString *courseFilePath = [plistFilePath substringToIndex:[plistFilePath rangeOfString:#"/" options:NSBackwardsSearch].location];
bool testDirectoryCreated = [[NSFileManager defaultManager]createDirectoryAtPath: courseFilePath
withIntermediateDirectories: YES
attributes: nil
error: NULL];
if (!testDirectoryCreated)
NSLog(#"error creating test directory.");
if (![data2 writeToFile:plistFilePath atomically:YES])
NSLog(#"error writing to path.");
}
}
}
#catch (NSException *exception) {
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle:#"Oops!" message:[NSString stringWithFormat: #"There was an error performing this operation. Please try again later. Error: %#", exception] delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles: nil];
[failureAlert show];
}
}
I try to do the same thing in v2 in the code as follow, is the code right?
-(void)downloadPlists
{
AWSS3 *s3 = [AWSS3 defaultS3];
AWSS3ListObjectsRequest *listObjectReq=[AWSS3ListObjectsRequest new];
listObjectReq.bucket=#"PLists";
[[[s3 listObjects:listObjectReq] continueWithBlock:^id(BFTask *task) {
if(task.error){
NSLog(#"the request failed. error %#",task.error);
}
if(task.result){
AWSS3ListObjectsOutput *listObjectsOutput=task.result;
NSArray *Plists = task.result; //Is the result of task in listObjectOutput a NSArray?
float numfile = 1;
float totalfiles = [Plists count];
for(AWSS3Object *file in listObjectsOutput.contents){
float percent = numfile/totalfiles;
progPercent = [NSNumber numberWithFloat:percent];
[self performSelectorOnMainThread:#selector(setProgressBar) withObject:progPercent waitUntilDone:YES];
numfile++;
NSString *key = [file key];
NSLog(#"key: %#", key);
if ([key rangeOfString:#".plist"].location != NSNotFound) {
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistFilePath = [NSString stringWithFormat:#"%#/Plists/%#",docDir, key];
NSLog(#"plistFilePath: %#", plistFilePath);
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
AWSS3TransferManagerDownloadRequest *downloadRequest = [AWSS3TransferManagerDownloadRequest new];
downloadRequest.bucket = #"PLists";
downloadRequest.key = key;
//downloadRequest.downloadingFileURL=[NSURL fileURLWithPath: #"???"]; I'm not sure the path. In sdk V1 there is no URL ?
[[transferManager download: downloadRequest] continueWithBlock:^id(BFTask *task) {
if (task.error) {
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle:#"Oops!"
message:[NSString stringWithFormat: #"There was an error performing this operation. Please try again later. Error: %#", task.error]
delegate:nil
cancelButtonTitle:#"Okay"
otherButtonTitles: nil];
[failureAlert show];
}
if (task.result) {
AWSS3TransferManagerDownloadOutput *downloadOutput = task.result;
NSData *data2 = [NSData dataWithData: downloadOutput.body];
NSString *courseFilePath = [plistFilePath substringToIndex:[plistFilePath rangeOfString:#"/" options:NSBackwardsSearch].location];
bool testDirectoryCreated = [[NSFileManager defaultManager]createDirectoryAtPath: courseFilePath
withIntermediateDirectories: YES
attributes: nil
error: NULL];
if (!testDirectoryCreated)
NSLog(#"error creating test directory.");
if (![data2 writeToFile:plistFilePath atomically:YES])
NSLog(#"error writing to path.");
}
return nil;
}];
}
}
return nil;
}
return nil;
}] waitUntilFinished]; //In the integration test still use the "waitUntilFinisher".But in the "Working with BFTask" said the continueWithBolck won't execute until the previous asychronous call has already finished exceuting?
}
AWSS3Object in v2 is equivalent to S3ObjectSummary in v1.
You are not invoking - listObjects:, so your v2 code snippet does not work. You should take a look at the integration test as an example. Note that you should avoid calling - waitUntilFinished in your production app. See Working with BFTask for further details.
I am using this code to upload videos to Youtube through my application - Uploading Videos on youtube . Now the thing is, the video is never being uploaded and I am wlways getting this error :
serviceBase:<GDataServiceGoogleYouTube: 0x155e3710> objectFetcher:<GDataHTTPUploadFetcher: 0x15662c10> failedWithStatus:400 data:<errors xmlns='http://schemas.google.com/g/2005'><error><domain>GData</domain><code>InvalidRequestUriException</code><internalReason>Exception message unavailable</internalReason></error></errors>
No matter what I do. My upload code for Youtube is as below :
- (void)uploadPressed{
NSString *devKey = #"some key";
GDataServiceGoogleYouTube *service = [self youTubeService];
[service setYouTubeDeveloperKey:devKey];
NSString *kGDataServiceDefaultUser = #"isome#gmail.com";
NSString *clientID = #"googleusercontent.com";
NSURL *url = [GDataServiceGoogleYouTube youTubeUploadURLForUserID:kGDataServiceDefaultUser
clientID:clientID];
// load the file data
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"vid1.mp4"];
NSData *myData = [[NSData alloc] initWithContentsOfFile:appFile] ;
// gather all the metadata needed for the mediaGroup
NSString *titleStr = #"Survey App";
GDataMediaTitle *title = [GDataMediaTitle textConstructWithString:titleStr];
NSString *categoryStr = #"Comedy";
GDataMediaCategory *category = [GDataMediaCategory mediaCategoryWithString:categoryStr];
[category setScheme:kGDataSchemeYouTubeCategory];
NSString *descStr = #"Survey Description.";
GDataMediaDescription *desc = [GDataMediaDescription textConstructWithString:descStr];
NSString *keywordsStr = #"survey";
GDataMediaKeywords *keywords = [GDataMediaKeywords keywordsWithString:keywordsStr];
BOOL isPrivate = YES;
GDataYouTubeMediaGroup *mediaGroup = [GDataYouTubeMediaGroup mediaGroup];
[mediaGroup setMediaTitle:title];
[mediaGroup setMediaDescription:desc];
[mediaGroup addMediaCategory:category];
[mediaGroup setMediaKeywords:keywords];
[mediaGroup setIsPrivate:isPrivate];
NSString *mimeType = [GDataUtilities MIMETypeForFileAtPath:documentsDirectory
defaultMIMEType:#"video/mp4"];
// create the upload entry with the mediaGroup and the file data
GDataEntryYouTubeUpload *entry;
entry = [GDataEntryYouTubeUpload uploadEntryWithMediaGroup:mediaGroup
data:myData
MIMEType:mimeType
slug:#"vid1.mp4"];
SEL progressSel = #selector(ticket:hasDeliveredByteCount:ofTotalByteCount:);
[service setServiceUploadProgressSelector:progressSel];
GDataServiceTicket *ticket;
ticket = [service fetchEntryByInsertingEntry:entry
forFeedURL:url
delegate:self
didFinishSelector:#selector(uploadTicket:finishedWithEntry:error:)];
[self setUploadTicket:ticket];
}
#pragma mark -
- (GDataServiceGoogleYouTube *)youTubeService {
static GDataServiceGoogleYouTube* service = nil;
if (!service) {
service = [[GDataServiceGoogleYouTube alloc] init];
[service setShouldCacheDatedData:YES];
[service setServiceShouldFollowNextLinks:YES];
[service setIsServiceRetryEnabled:YES];
}
// update the username/password each time the service is requested
NSString *kGDataServiceDefaultUser = #"isome#gmail.com";
NSString *password = #"passwrd";
[GDataHTTPFetcher setIsLoggingEnabled:YES];
if ([kGDataServiceDefaultUser length] > 0 && [password length] > 0) {
[service setUserCredentialsWithUsername:kGDataServiceDefaultUser
password:password];
} else {
// fetch unauthenticated
[service setUserCredentialsWithUsername:nil
password:nil];
}
NSString *devKey = #"some key";
[service setYouTubeDeveloperKey:devKey];
return service;
}
// progress callback
- (void)ticket:(GDataServiceTicket *)ticket
hasDeliveredByteCount:(unsigned long long)numberOfBytesRead
ofTotalByteCount:(unsigned long long)dataLength {
// [mProgressView setProgress:(double)numberOfBytesRead / (double)dataLength];
}
// upload callback
- (void)uploadTicket:(GDataServiceTicket *)ticket
finishedWithEntry:(GDataEntryYouTubeVideo *)videoEntry
error:(NSError *)error {
if (error == nil) {
// tell the user that the add worked
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Uploaded!"
message:[NSString stringWithFormat:#"%# succesfully uploaded",
[[videoEntry title] stringValue]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:[NSString stringWithFormat:#"Error: %#",
[error description]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
// [mProgressView setProgress: 0.0];
[self setUploadTicket:nil]
OK I have app for iPad that reads magazines. All previous issues works fine. I manage to make new issue (before it was done by other guy that left the firm) and to run it in simulator and on device without problems.
Now I add row for new issue of magazine in database and compress all pictures and multimedia by ZIP tool and divide them by MacHacha (because Java class that uploads demand parts from MacHacha to upload one by one) and upload it on server. In App store I downloaded magazine and can see new issue. On server new row is good have all good parameters and the size is adequate to size on disk.
When new issue finnish download it shows me error. I tried same procedure from simulator and in OUTPUT in the moment it crashes shows me decompression error (0).
I supposed that problem is with putting parts together with MacHacha. Can anyone help or give me that catch that solves this problem.
if it will help I can upload new issue and provide link (it's free) I it will be helpful for You guys and girls :)
http://www.mazzantieditori.it/applicazioni/219-nycit-italian-american-magazine.html
link for application. In library there is few issues and the last one is new (Giugno 2011).
I will provide code for that method that gives me string for mistake:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// controllo se il receipt è corretto e faccio partire il download
if(min == 0 && [receivedData length]
NSString *file = [[self documentsDir:1] stringByAppendingPathComponent:#"archivio.zip"];
if (max <= num && !cancelDownload) {
self.progressBar.progress = (1.0f/num)*min;
min = max+1;
max += 5;
// creo directory per l'elemento scaricato
BOOL isDir = NO;
if(![[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDir]) {
NSError *error;
//creo directory
[[NSFileManager defaultManager] createDirectoryAtPath:[self documentsDir:1] withIntermediateDirectories:YES attributes:nil error:&error];
//creo file vuoto
[[NSFileManager defaultManager] createFileAtPath:file contents:nil attributes:nil];
}
NSFileHandle *handler = [NSFileHandle fileHandleForWritingAtPath:file];
if(handler) {
[handler seekToEndOfFile];
[handler writeData:receivedData];
}
NSLog(#"Received %d bytes of data; min: %i max: %i",[receivedData length],min,max);
[receivedData setLength:0];
// questa è la seconda invocazione
[self downloadArchivePart:#"verified"];
[connection release];
return;
}
NSFileManager *man = [[NSFileManager alloc] init];
NSDictionary *attrs = [man attributesOfItemAtPath:file error: NULL];
//UInt32 result =
NSNumber *size = [attrs objectForKey:NSFileSize];
//int length = [receivedData length];
NSLog(#"Succeeded! Received %i bytes of data",[size intValue]);
[man release];
//1.038.090 è il numero di byte della parte più piccola dell'archivio
if([size intValue] >= kMinPartSize) {
NSLog(#"prod %#",self.prodName);
if(self.prodName == nil || [self.prodName isEqualToString:#""]) self.prodName = prodId;
NSError *error;
BOOL ok = [TWZipArchive unzipFileAtPath:file toDestination:[self documentsDir:1] overwrite:YES password:nil error:&error];
//unzipFileAtPath:file toDestination:[self documentsDir]];
NSString *msg;
if(ok) {
NSLog(#"decompression successfull");
self.progressBar.progress = 1.0f;
NSFileManager *fm = [NSFileManager defaultManager];
[fm removeItemAtPath:file error:&error];
msg = #"Download completed: new issue added in libray";
NSMutableArray *array;
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSString *path = [[self documentsDir:0] stringByAppendingPathComponent:#"downloaded.plist"];
if(![[NSFileManager defaultManager] fileExistsAtPath:path]) {
[dict setObject:prodId forKey:#"id"];
[dict setObject:prodName forKey:#"titolo"];
array = [NSArray arrayWithObject:dict];
[array writeToFile:path atomically:YES];
}
array = [NSMutableArray arrayWithContentsOfFile:path];
BOOL exist = NO;
for (int i=0; i<[array count]; i++) {
if ([[[array objectAtIndex:i] objectForKey:#"id"] isEqualToString:prodId]) {
exist = YES;
//prodId = [NSString stringWithFormat:#"%#%i",prodId,i];
}
}
if(exist == NO) {
[dict setObject:prodId forKey:#"id"];
[dict setObject:prodName forKey:#"titolo"];
[array insertObject:dict atIndex:0]; //sempre in testa l'ultimo elemento scaricato
[array writeToFile:path atomically:YES];
}
}
else {
NSLog(#"decompression error");
msg = #"An error has occurred";
}
//[myAlert release];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"NYC.IT"
message:#"Download completed: new issue added in libray"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
//[alert release];
}else {
if(cancelDownload == YES) {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"NYC.IT"
message:#"Download stopped for user action"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
}else {
NSString *errFile = [[self documentsDir:1] stringByAppendingPathComponent:#"errFile.html"];
[receivedData writeToFile:errFile atomically:YES];
NSLog(#"err : %#",errFile);
NSLog(#"scrittura error file eseguita");
NSLog(#"receipt non valido");
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"NYC.IT"
message:#"Downloading error: please retry later!"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
}
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
progressBar.hidden = YES;
// release the connection, and the data object
[connection release];
//[receivedData release];
}
Thanks in Advance...
I dont know about x-code but this is useful library
http://www.winimage.com/zLibDll/minizip.html