iOS objC upload file to firebase not happening - ios

I need to upload a file to firebase, firebase account is set, iOS project is connecting...
The file exists, and I check for file size before sending...
when I try the upload the process starts, but I get the error:
Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, please check the server response
This is the path for the file:
/var/mobile/Containers/Data/PluginKitPlugin/A14B0460-06E7-4EC0-80CE-9C27B5B70BC2/Documents/img.JPG
My doubt is if I have "riversRef" property correctly set?... What is missing?
- (void)uploadFileTest:(NSURL*)url {
// reference
FIRStorage * storage = [FIRStorage storage];
// Create a root reference
FIRStorageReference *storageRef = [storage reference];
FIRStorageReference *riversRef = [storageRef child:#"images/rios.jpg"]; // is this correct?
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init];
metadata.contentType = #"image/jpeg";
NSLog(#"storageRef: %#", storageRef);
NSLog(#"url path: %#", [url path]);
NSLog(#"metadata : %#", metadata);
//object size?
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]]){
long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:url.absoluteString error:nil][NSFileSize] longLongValue];
NSLog(#"sik: %lld", fileSize);
}else{
NSLog(#"nanais");
}
NSURL *curaul = [NSURL fileURLWithPath:[url path]];
// Upload file and metadata to the object 'images/rios.jpg'
FIRStorageUploadTask *uploadTask = [riversRef putFile:curaul metadata:metadata];
// Listen for state changes, errors, and completion of the upload.
[uploadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) {
// Upload resumed, also fires when the upload starts
NSLog(#"upload started");
}];
[uploadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) {
// Upload paused
NSLog(#"paused");
}];
[uploadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) {
// Upload reported progress
double percentComplete = 100.0 * (snapshot.progress.completedUnitCount) / (snapshot.progress.totalUnitCount);
NSLog(#"percentComplete :: %f", percentComplete);
}];
[uploadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) {
// Upload completed successfully
NSLog(#"successfully");
}];
// Errors only occur in the "Failure" case
[uploadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) {
NSLog(#"errore :: %#", snapshot.error.description);
if (snapshot.error != nil) {
switch (snapshot.error.code) {
case FIRStorageErrorCodeObjectNotFound:
// File doesn't exist
break;
case FIRStorageErrorCodeUnauthorized:
// User doesn't have permission to access file
break;
case FIRStorageErrorCodeCancelled:
// User canceled the upload
break;
/* ... */
case FIRStorageErrorCodeUnknown:
// Unknown error occurred, inspect the server response
break;
}
}
}];
}
Is the response to unknown error?
How to fix upload?, thanks

Related

AdobeAssetFile: can't tracking upload progress

I'm trying to upload image to Adobe Creative Cloud using method create:folder:dataPath:contentType:progressBlock:successBlock:cancellationBlock:errorBlock of AdobeAssetFile. File upload succesfully, but I can't track upload progress with progressBlock. This block just don't invocated.
- (void)sendImageWithURL:(NSURL *)imageURL {
NSString *imageName = [imageURL lastPathComponent];
[AdobeAssetFile create:imageName
folder:[AdobeAssetFolder root]
dataPath:imageURL
contentType:[AdobeAssetMimeTypes mimeTypeForExtension:#"jpg"]
collisionPolicy:AdobeAssetFileCollisionPolicyAppendUniqueNumber
progressBlock:^(double fractionCompleted) {
NSLog(#"Progress: %f", fractionCompleted);
}
successBlock:^(AdobeAssetFile *file) {
NSLog(#"Operation is complete");
}
cancellationBlock:^{
NSLog(#"Operation is canceled");
}
errorBlock:^(NSError *error){
NSLog(#"Error is occur: %#", error.localizedDescription);
}
];
}
What's wrong with this code? And why progressBlock not invocated?
I'm using Adobe Creative SDK v0.13.2139.
There is nothing wrong with your code. This is a known issue. A fix is in the works.

AWS S3 media transfer slow & pause when application send to background in IOS

I am developing an chat app where I transfer media like videos / audio/ images.
When the transfer is done with below code snippet, the transfer is smooth on Wifi but is very very slow when moved to 3G network.
Also another issue is when I go in background the AWS SDK pause the transfer and resumes when I come in foreground.
1) How can I make the transfer fast as I have tried changing the AWS region still no success.
2) Also use the S3Background transfer example compared to AWS S3 transfer manager used but the download paused when I press home button.
Below is my code snipped.
//Upload function
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = S3BucketName;
User *userMO = .....my user details
NSString *fileName = [[filePath componentsSeparatedByString:#"/"] lastObject];
uploadRequest.key = [userMO.user_pool_id stringByAppendingPathComponent:fileName];
NSURL *uploadFileURL = [NSURL fileURLWithPath:filePath];
uploadRequest.body = uploadFileURL;
uploadRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];
NSString *fileContentTypeStr = #"image/jpg";
if ([FileManager isVideoFile:fileName]) {
// fileContentTypeStr = [NSString stringWithFormat:#"video/%#",[[fileName pathExtension] lowercaseString]];
fileContentTypeStr = [NSString stringWithFormat:#"video/quicktime"];
}
else if ([FileManager isImageFile:fileName]) {
fileContentTypeStr = [NSString stringWithFormat:#"image/%#",[[fileName pathExtension] lowercaseString]];
}
else if ([FileManager isAudioFile:fileName]) {
fileContentTypeStr = [NSString stringWithFormat:#"audio/%#",[[fileName pathExtension] lowercaseString]];
}
uploadRequest.contentType = fileContentTypeStr;
[[transferManager upload:uploadRequest] continueWithBlock:^id(AWSTask *task) {
if (task.error) {
if ([task.error.domain isEqualToString:AWSS3TransferManagerErrorDomain]) {
switch (task.error.code) {
case AWSS3TransferManagerErrorCancelled:
{
//updating ui to notify cancel
}
break;
case AWSS3TransferManagerErrorPaused:
{
//updating ui to notify paused
}
break;
default:
{
NSLog(#"Upload task failed: %#",[task.error localizedDescription]);
//updating ui to notify failed
}
break;
}
} else {
NSLog(#"Upload task failed: %#",[task.error localizedDescription]);
//updating ui to notify failed
}
}
if (task.result)
{
//updating ui to notify finished
}
return nil;
}];
if(uploadRequest.state == AWSS3TransferManagerRequestStateRunning)
{
//updating ui to notify progress
}
//Add the request to the current upload cache handler entry as handle
Any body have any suggestions and faced similar issue.
Use AWS background transfer not AWS transfer manager to use the background mode supported transfer.

How to do incremental writing for UIDocument in iCloud?

I have UIDocument in iCloud ubiquitous container and I need to append data to file while saving document. I override readFromURL:: and writeContents::::: method according UIDocument documentation:
-(BOOL) writeContents:(id)contents toURL:(NSURL*)url forSaveOperation:(UIDocumentSaveOperation)saveOperation originalContentsURL:(NSURL*)originalContentsURL error:(NSError *__autoreleasing *)outError
{
NSFileCoordinator* coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:self];
NSError* error = nil;
[coordinator coordinateWritingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) {
NSData* data = contents; //correct, non-empty NSData
///[data writeToFile:newURL :] works, but overwrite original file
NSOutputStream* stream =[[NSOutputStream alloc] initWithURL:newURL append:YES];
if (stream)
{
NSInteger written = [stream write:data.bytes maxLength:data.length];
if (written != data.length)
{
//failed here, written == -1
NSLog(#"Write data to UIDocument failed: %#, error: %#", newURL, stream.streamError);
}
}
else
{
NSLog(#"Write data to iCloudDocument failed: %#", newURL);
}
}];
if (error)
{
NSLog(#"Coordinated write failed %#, error: %#", url, error);
*outError = error;
}
return error == nil;
}
Accessor block has different newURL, for example:
url: file:///private/var/mobile/Library/Mobile%20Documents/XXXXXXX~com~test~test/test.doc
newURL: file:///private/var/mobile/Applications/5631D484-7661-4E9E-A342-B25297FC0E18/tmp/(A%20Document%20Being%20Saved%20By%20test%20)/test.doc.
[stream write::] failed, because newURL file dosn't exists and I can't append data, only create file with all document's content.
Document editing code:
NSURL* url = [self.containerURL URLByAppendingPathComponent:kCloudDocumentName];
MyDocument* document = [[MyDocument alloc] initWithFileURL:url];
[document openWithCompletionHandler:^(BOOL success) {
if (success)
{
//update some document data
[self updateData:document completion:nil];
[document closeWithCompletionHandler:^(BOOL success) {
//failed here!
}];
}
}];
MyDocument exists in ubiquitous container at url and document has Normal state.
How I can do incremental writing in this case? Whats wrong?
After changing data in your UIDocumnet you can use:
-[UIDocumnet saveToURL:UIDocumnet.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:nil];
Not sure, it's right or not but it works in my app. If it's wrong, correct me please somebody.
You may need to overwrite this method in your subclass of UIDocumnet:
- (id) contentsForType:(NSString *)typeName error:(NSError **)outError

Youtube video upload fails after 100 % progress for some users with Backend Error code:-32099

I have added youtube api v3 using google api's objective-C client in my app to upload video to youtube. Testers of the app (in different country) reports that they are unable to upload video to youtube. Video uploading fails after reaching to 100 % progress with backend error. Where as I am not facing that issue in my end here in India. Testers also confirms that youtube video upload is working fine when uploaded using youtube ios app or some different app. They also tried uploading videos from multiple accounts but with same result.
The error log from device console is:
Error Domain=com.google.GTLJSONRPCErrorDomain Code=-32099 "The operation couldn’t be completed. (Backend Error)" UserInfo=0x2438c380 {error=Backend Error, GTLStructuredError=GTLErrorObject 0x27ea3990: {message:"Backend Error" code:-32099 data:[1]}, NSLocalizedFailureReason=(Backend Error)}
and my code that I am using to upload video to youtube is:
GTMOAuth2Authentication *auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:YoutubeOAuthKeyChain clientID:GoogleAPIClientID clientSecret:GoogleAPIClientSecret];
if (!auth) {
[self signInToGoogle];
}else{
if ([auth canAuthorize] && auth.userEmail) {
//Force the api to refresh access token if needed
[auth authorizeRequest:Nil completionHandler:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!error) {
NSLog(#"Youtube: App authorized. Uploading video now");
self.youTubeService.authorizer = auth;
GTLYouTubeVideoStatus *status = [GTLYouTubeVideoStatus object];
status.privacyStatus = #"public";
GTLYouTubeVideoSnippet *snippet = [GTLYouTubeVideoSnippet object];
snippet.title = _captionTextView.text;
snippet.descriptionProperty = #"This is a test video";
GTLYouTubeVideo *video = [GTLYouTubeVideo object];
video.status = status;
video.snippet = snippet;
NSString *filename = [_moviePath lastPathComponent];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:_moviePath];
if (fileHandle) {
NSString *mimeType = [self MIMETypeForFilename:filename
defaultMIMEType:#"video/mp4"];
GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithFileHandle:fileHandle MIMEType:mimeType];
uploadParameters.uploadLocationURL = nil;
//uploadParameters.shouldSendUploadOnly = YES;
GTLQueryYouTube *query = [GTLQueryYouTube queryForVideosInsertWithObject:video part:#"snippet,status" uploadParameters:uploadParameters];
GTLServiceYouTube *service = self.youTubeService;
GTLServiceTicket *ticket = [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!error) {
NSLog(#"Youtube video upload completed ");
}else{
NSLog(#"error completing request with error: %#", error);
}
});
}];
[ticket setUploadProgressBlock:^(GTLServiceTicket *ticket, unsigned long long totalBytesWritten, unsigned long long totalBytesExpectedToWrite) {
float progress = ((float)totalBytesWritten / (float)totalBytesExpectedToWrite) * 100.0f;
NSLog(#"%f %% uploaded");
}];
}
}else{
//Error authorizing the request
NSLog(#"error authorizing request with error: %#", error);
}
});
}];
}else{
//Refresh access token
[self signInToGoogle];
}
}
This issue started just 2 weeks ago. I have no idea if this is a server side issue of some issue with my app. Has anyone also have the same issue?

Rename an iCloud document

The problem
What I have so far is code that creates a new local file and deletes the iCloud file.
Is it possible to rename an iCloud document, so that it stays in iCloud?
GarageBand can do it. It's possible to rename an iCloud song. After the rename is done, the song is still in iCloud. However GarageBand is an Apple app, so it may use private apis.
My current code:
- (void)moveFrom:(NSURL*)sourceURL
moveTo:(NSString*)destinationName
completion:(void (^)())completion
{
MyDocument *document = [[MyDocument alloc] initWithFileURL:sourceURL];
[document openWithCompletionHandler:^(BOOL success)
{
NSURL *fileURL = [self.localRoot URLByAppendingPathComponent:destinationName];
DLog(#"Create %#", fileURL);
[document saveToURL:fileURL
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success)
{
NSLog(#"Saved %#", fileURL);
[document closeWithCompletionHandler:^(BOOL success) {
// Delete the old document from a secondary thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^()
{
NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[fileCoordinator coordinateWritingItemAtURL:sourceURL
options:NSFileCoordinatorWritingForDeleting
error:nil
byAccessor:^(NSURL* writingURL) {
NSFileManager* fileManager = [[NSFileManager alloc] init];
[fileManager removeItemAtURL:writingURL error:nil];
DLog(#"Deleted %#", sourceURL);
completion();
}];
});
}];
}];
}];
}
Update: Still no luck
I have found out that -setUbiquitous:itemAtURL:destinationURL:error: cannot be used for renaming documents.
If I invoke [setUbiquitous:NO itemAtURL:oldLocalURL destinationURL:newLocalURL error:&error] on an already local file, then:
Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be
completed. (Cocoa error 512.)" UserInfo=0x1fdf6730
{NSURL=file://localhost/var/mobile/Applications/4BABA000-B100-49FC-B928-B0F403FC75FF/Documents/LocalDrawing.td2/,
NSUnderlyingError=0x20940e80 "The operation couldn’t be completed.
(LibrarianErrorDomain error 2 - Cannot disable syncing on a unsynced
item.)"}
If I invoke [setUbiquitous:YES itemAtURL:oldCloudURL destinationURL:newCloudURL error:&error] on an already cloud file, then:
Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be
completed. (Cocoa error 512.)" UserInfo=0x208e9820
{NSURL=file://localhost/var/mobile/Library/Mobile%20Documents/22DR89XVRF~com~opcoders~triangle-draw/Documents/CloudDrawing.td2/,
NSUnderlyingError=0x208d45b0 "The operation couldn’t be completed.
(LibrarianErrorDomain error 2 - Cannot enable syncing on a synced
item.)"}
Thus -setUbiquitous:itemAtURL:destinationURL:error: cannot be used for renaming documents.
I have finally solved it. This is my code so far:
- (void)_moveURL:(NSURL*)sourceURL
destURL:(NSURL*)destinationURL
success:(void (^)())successBlock
failure:(void (^)(NSError *))failureBlock
{
NSParameterAssert(sourceURL);
NSParameterAssert(destinationURL);
NSParameterAssert(successBlock);
NSParameterAssert(failureBlock);
// Do the actual renaming
__block NSError *moveError = nil;
__block BOOL moveSuccess = NO;
void (^accessor)(NSURL*, NSURL*) = ^(NSURL *newURL1, NSURL *newURL2) {
NSFileManager *fileManager = [[NSFileManager alloc] init];
moveSuccess = [fileManager moveItemAtURL:sourceURL toURL:destinationURL error:&moveError];
};
// Coordinate renaming
NSError *coordinatorError = nil;
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[coordinator coordinateWritingItemAtURL:sourceURL
options:NSFileCoordinatorWritingForMoving
writingItemAtURL:destinationURL
options:NSFileCoordinatorWritingForReplacing
error:&coordinatorError
byAccessor:accessor];
if (moveSuccess) {
successBlock();
return;
}
if (moveError) {
failureBlock(moveError);
return;
}
if (coordinatorError) {
failureBlock(coordinatorError);
return;
}
NSAssert(NO, #"should not happen");
}
There is an easier way to rename item at any given URL, including iCloud URLs.
url.setResourceValue(newName, forKey: NSURLNameKey)
I am using this in my cocoa app's production code.
Edit:
In Swift 5, this looks a little different, but still works well:
var resourceValues = URLResourceValues()
resourceValues.name = newName
try previousFileURL.setResourceValues(resourceValues)

Resources