これは、NSStreamを使用してFTPファイルのアップロードを実装した方法であり、問題なく正常に動作しますが、接続が失われた場合、またはアップロード中にユーザーが誤ってアプリを閉じた場合に備えて、ファイルのアップロードを再開する方法を理解できませんでした進行中。
@implementation QFTPOperation
-(id)uploadFile:(NSString *)filePath
{
NSURL *localpath = [NSURL URLWithString:filePath];
NSLog(@"file url: %@",[localpath path]);
if([[NSFileManager defaultManager] fileExistsAtPath:[localpath path]]) {
NSLog(@"files exists");
}
self.readStream = [NSInputStream inputStreamWithFileAtPath:[[NSURL URLWithString:filePath] path]];
[self.readStream open];
NSURL *uploadUrl = [NSURL URLWithString:@"ftp://domain.example.com/test.png"];
uploadUrl = CFBridgingRelease(
CFURLCreateCopyAppendingPathComponent(NULL, (__bridge CFURLRef) uploadUrl, (__bridge CFStringRef) [filePath lastPathComponent], false)
);
NSLog(@"upload url: %@",uploadUrl);
self.writeStream = CFBridgingRelease(
CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) uploadUrl)
);
[[self writeStream] setDelegate:self];
[[self writeStream] scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[[self writeStream] setProperty:@"foo" forKey:(id)kCFStreamPropertyFTPUserName];
[[self writeStream] setProperty:@"bar" forKey:(id)kCFStreamPropertyFTPPassword];
[[self writeStream] open];
while ([[self writeStream] hasSpaceAvailable])
{
NSLog(@"yes ready");
NSInteger bufferOffset = 0;
NSInteger bufferLimit = 0;
UInt8 buffer[1024];
if (bufferOffset == bufferLimit) {
NSInteger bytesRead;
bytesRead = [self.readStream read:buffer maxLength:1024];
if (bytesRead == -1) {
NSLog(@"faild to readstream");
[self closeStream];
} else if (bytesRead == 0) {
NSLog(@"read completed");
[self closeStream];
} else {
NSLog(@"bytes read");
bufferOffset = 0;
bufferLimit = bytesRead;
}
}
if (bufferOffset != bufferLimit) {
NSLog(@"yes waiting to write");
NSInteger bytesWritten;
bytesWritten = [self.writeStream write:&buffer[1024] maxLength:bufferLimit - bufferOffset];
if (bytesWritten == -1) {
NSLog(@"failed to write");
[self closeStream];
} else {
bufferOffset += bytesWritten;
}
}
}
return self;
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(@"yes stream open");
break;
case NSStreamEventHasBytesAvailable:
break;
case NSStreamEventHasSpaceAvailable: {
NSLog(@"yes space available");
NSInteger bufferOffset = 0;
NSInteger bufferLimit = 0;
UInt8 buffer[1024];
if (bufferOffset == bufferLimit) {
NSInteger bytesRead;
bytesRead = [self.readStream read:buffer maxLength:1024];
if (bytesRead == -1) {
NSLog(@"faild to readstream");
[self closeStream];
} else if (bytesRead == 0) {
NSLog(@"read completed");
[self closeStream];
} else {
NSLog(@"bytes read");
bufferOffset = 0;
bufferLimit = bytesRead;
}
}
if (bufferOffset != bufferLimit) {
NSLog(@"yes waiting to write");
NSInteger bytesWritten;
bytesWritten = [self.writeStream write:&buffer[1024] maxLength:bufferLimit - bufferOffset];
if (bytesWritten == -1) {
NSLog(@"failed to write");
[self closeStream];
} else {
bufferOffset += bytesWritten;
}
}
}
break;
case NSStreamEventEndEncountered:
NSLog(@"error occurred");
[self closeStream];
break;
case NSStreamEventErrorOccurred:
NSLog(@"error occurred");
[self closeStream];
break;
case NSStreamEventNone:
break;
default:
break;
}
}
-(void)closeStream
{
[[self writeStream] removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[[self writeStream] setDelegate:nil];
[[self writeStream] close];
self.writeStream = nil;
[[self readStream] close];
self.readStream = nil;
}
ユーザーが途中でアプリを終了した場合、ユーザーが 200 MB をアップロードしている場合、100 MB がアップロードされたとします。最初からやり直すのではなく、100 MB からアップロードを再開したいとします。
事前に感謝します