问题描述
我有一个iOS应用程序,它使用Core Data进行持久数据存储。我将Dropbox集成为用户执行持久存储文件(appname.sqlite)备份的一种方式。
I have an iOS app that uses Core Data for persistent data storage. I integrated Dropbox as a way for users to perform a a backup of the persistent store file (appname.sqlite).
UIButton调用方法查看文件是否已存在在Dropbox上:
A UIButton calls a method to see if a file already exists on Dropbox:
if([[DBSession sharedSession]isLinked])
{
NSString *folderName = [[self.dateFormatter stringFromDate:[NSDate date]] stringByReplacingOccurrencesOfString:@"/" withString:@"-"];
NSString *destinationPath = [NSString stringWithFormat:@"/GradeBook Pro/Backup/%@/",folderName];
self.metadataIndex = METADATA_REQUEST_BACKUP;
[self.restClient loadMetadata:destinationPath];
}
loadedMetadata委托方法使用现有文件的转数启动上传(如果存在的话)。
The loadedMetadata delegate method initiates the upload with the rev number of the existing file (if one exists).
-(void) restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata
{
SAVE_CORE_DATA;
NSString *folderName = [[self.dateFormatter stringFromDate:[NSDate date]] stringByReplacingOccurrencesOfString:@"/" withString:@"-"];
NSString *documentsDirectory = DOCUMENTS_DIRECTORY;
NSString *sourcePath = [NSString stringWithFormat:@"%@/GradeBookPro.sqlite", documentsDirectory];
NSString *destinationPath = [NSString stringWithFormat:@"/GradeBook Pro/Backup/%@/",folderName];
[self.restClient uploadFile:@"GradeBookPro.sqlite" toPath:destinationPath withParentRev:[[metadata.contents lastObject]rev] fromPath:sourcePath];
}
这适用于完美网络连接上相当小的文件或大文件但上传过程中的任何小错误都会取消整个过程。我想切换到使用分块上传方法,但我不知道如何实际执行.sqlite文件的'分块'。
This works well for reasonably small files or large files over a perfect network connection but any small error during the upload cancels the whole process. I would like to switch to using the chunked upload methods but I'm at a loss as to how to actually do the 'chunking' of the .sqlite file.
I似乎无法找到任何使用我可以学习的分块上传的示例应用程序,文档只是说以块的形式提供文件。
I can't seem to find any sample apps that are using the chunked upload that I can learn from and the documentation simply says to provide the file in chunks.
所以,我的问题是:
-
分块上传是否正确解决用户通过可能不稳定的网络连接上传大文件的问题?
Is the chunked upload the right approach to addressing the user issues with uploading large files over a possibly spotty network connection?
您是否可以指向分块文件的示例代码/应用/文档?我很满意Dropbox SDK。
Can you point me to sample code / app / documentation for 'chunking' a file? I'm pretty comfortable with the Dropbox SDK.
谢谢!
推荐答案
我将自己回答这个问题,以防万一其他人有同样的问题。
I'm going to answer this myself just in case anyone else has the same issue.
事实证明,我这样做比实际需要的更困难。 Dropbox SDK处理文件分块,所以我只需要启动传输并对委托调用做出反应。使用的方法是:
It turns out that I was making this way more difficult than it needed to be. The Dropbox SDK handles chunking the files so I just needed to initate the transfer and react to the delegate calls. The methods used are:
要发送文件块 - 对于第一个块,使用nil表示uploadId,0表示偏移量:
To send a file chunk - for the first chunk, use nil for the uploadId and 0 for the offset:
- (void)uploadFileChunk:(NSString *)uploadId offset:(unsigned long long)offset fromPath:(NSString *)localPath;
发送最后一个块后,使用此方法提交上传:
After sending the last chunk, use this method to commit the upload:
- (void)uploadFile:(NSString *)filename toPath:(NSString *)parentFolder withParentRev:(NSString *)parentRev fromUploadId:(NSString *)uploadId;
我按如下方式处理了委托方法:
I handled the delegate method as follows:
- (void)restClient:(DBRestClient *)client uploadedFileChunk:(NSString *)uploadId newOffset:(unsigned long long)offset fromFile:(NSString *)localPath expires:(NSDate *)expiresDate
{
unsigned long long fileSize = [[[NSFileManager defaultManager]attributesOfItemAtPath:[FileHelper localDatabaseFilePath] error:nil]fileSize];
if (offset >= fileSize)
{
//Upload complete, commit the file.
[self.restClient uploadFile:DATABASE_FILENAME toPath:[FileHelper remoteDatabaseDirectory] withParentRev:self.databaseRemoteRevision fromUploadId:uploadId];
}
else
{
//Send the next chunk and update the progress HUD.
self.progressHUD.progress = (float)((float)offset / (float)fileSize);
[self.restClient uploadFileChunk:uploadId offset:offset fromPath:[FileHelper localDatabaseFilePath]];
}
}
由于我试图解决的主要问题是处理不良连接我为失败的块上传实现了委托方法:
Since the main problem that I was trying to address was handling poor connections I implemented delegate method for failed chunk uploads:
- (void)restClient:(DBRestClient *)client uploadFileChunkFailedWithError:(NSError *)error
{
if (error != nil && (self.uploadErrorCount < DROPBOX_MAX_UPLOAD_FAILURES))
{
self.uploadErrorCount++;
NSString* uploadId = [error.userInfo objectForKey:@"upload_id"];
unsigned long long offset = [[error.userInfo objectForKey:@"offset"]unsignedLongLongValue];
[self.restClient uploadFileChunk:uploadId offset:offset fromPath:[FileHelper localDatabaseFilePath]];
}
else
{
//show an error message and cancel the process
}
}
这篇关于使用iOS Dropbox SDK进行核心数据的分块上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!