将文件上传到FTP

时间:2018-02-21 14:06:07

标签: swift ftp

我正在尝试使用Swift上传文件。 我发现了Apple(Objective-C)的这篇(写得不好)的教程:

我试图在Swift中实现它,但是在解除回调函数中的指针时停滞不前:

func upload(filepath:String, url:String){
        do {
            let attr:NSDictionary? = try FileManager.default.attributesOfItem(atPath: filepath) as NSDictionary;
            if attr == nil { return; }
            let size:UInt64? = attr?.fileSize();
            if size==nil { return; }
            var info = MyStreamInfo(writeStream: CFWriteStreamCreateWithFTPURL(nil, CFURLCreateWithString(nil,url as CFString, nil)) as! CFWriteStream,
                                    readStream: CFReadStreamCreateWithFile(nil, CFURLCreateWithString(nil, filepath as CFString, nil)),
                                    /*proxyDict: CFDictionary(), */fileSize: size!, totalBytesWritten: 0, leftOverByteCount: 0, buffer: UnsafeMutablePointer<UInt8>.allocate(capacity: bSize));
            var myContext=CFStreamClientContext(version: 0, info: &info, retain: nil, release: nil, copyDescription: nil);
            //myContext.info = info;
            CFReadStreamOpen(info.readStream);

            CFWriteStreamSetProperty(info.writeStream, CFStreamPropertyKey(kCFStreamPropertyFTPUserName), username as CFTypeRef);
            CFWriteStreamSetProperty(info.writeStream, CFStreamPropertyKey(kCFStreamPropertyFTPPassword), password as CFTypeRef);
            CFWriteStreamSetProperty(info.writeStream, CFStreamPropertyKey(kCFStreamPropertyFTPProxyHost), hostname as CFTypeRef);
            CFWriteStreamSetProperty(info.writeStream, CFStreamPropertyKey(kCFStreamPropertyFTPProxyPort), port as CFTypeRef);

            CFWriteStreamSetClient(info.writeStream, CFStreamEventType.canAcceptBytes.rawValue, writeCB as! CFWriteStreamClientCallBack, &myContext);


        } catch let error as NSError  {
            print(error);
        }



    }

    func writeCB(stream:CFWriteStream, event:CFStreamEventType, myptr: UnsafeMutableRawPointer) {
        var info:MyStreamInfo;
        var totalBytesRead:Int32 = 0;
        repeat {
            var bytesRead:Int32 = 0;
            var bytesWritten:Int32 = 0;
            if info.leftOverByteCount>0 {
                bytesRead = Int32(info.leftOverByteCount);
            } else {
                bytesRead = Int32(CFReadStreamRead(info.readStream, info.buffer, bSize));
                if (bytesRead < 0){
                    print("error");
                    return;
                }
                totalBytesRead += bytesRead;
            }
            bytesWritten = Int32(CFWriteStreamWrite(info.writeStream, info.buffer, CFIndex(bytesRead)));
            if bytesWritten > 0 {
                info.totalBytesWritten += UInt32(bytesWritten);

                if bytesWritten < bytesRead {
                    info.leftOverByteCount = UInt32(bytesRead - bytesWritten);
                    memmove(info.buffer, info.buffer.advanced(by: Int(bytesWritten)), Int(info.leftOverByteCount));
                } else {
                    info.leftOverByteCount = 0;
                }
            } else {
                if bytesWritten < 0  {
                    print("error");
                    break;
                }
            }
        } while(CFWriteStreamCanAcceptBytes(info.writeStream));

    }

如何从指针中获取MyStreamInfo对象? 我休息了吗? 用户名,密码等当然是我在其他地方设置的班级成员。

1 个答案:

答案 0 :(得分:0)

您可以使用FilesProvider库来处理FTP。它没有使用已弃用的CFWriteStreamCreateWithFTPURL API并从头开始实现FTP协议,并提供了一个高级FileManager API来处理FTP / FTPS。

您可以看到示例实现here