63784
Swift初心者です。  
Swiftを使って、FTPでJSONファイルをアップロードしたいです。  
[それらしき記事がGitHubにあった](https://gist.github.com/Nirma/fb9991be776107d17fdcd6ed2aa02876)のでそれを参考にして作っていこうかと思っています。

```

    public class FTPUpload {
        fileprivate let ftpBaseUrl: String
        fileprivate let directoryPath: String
        fileprivate let username: String
        fileprivate let password: String
    
        public init(baseUrl: String, userName: String, password: String, directoryPath: String) {
            self.ftpBaseUrl = baseUrl
            self.username = userName
            self.password = password
            self.directoryPath = directoryPath
        }
    }
    
    // MARK: - Steam Setup
    extension FTPUpload {
        private func setFtpUserName(for ftpWriteStream: CFWriteStream, userName: CFString) {
            let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertyFTPUserName)
            CFWriteStreamSetProperty(ftpWriteStream, propertyKey, userName)
        }
    
        private func setFtpPassword(for ftpWriteStream: CFWriteStream, password: CFString) {
            let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertyFTPPassword)
            CFWriteStreamSetProperty(ftpWriteStream, propertyKey, password)
        }
    
        fileprivate func ftpWriteStream(forFileName fileName: String) -> CFWriteStream? {
            let fullyQualifiedPath = "ftp://\(ftpBaseUrl)/\(directoryPath)/\(fileName)"
    
            guard let ftpUrl = CFURLCreateWithString(kCFAllocatorDefault, fullyQualifiedPath as CFString, nil) else { return nil }
            let ftpStream = CFWriteStreamCreateWithFTPURL(kCFAllocatorDefault, ftpUrl)
            let ftpWriteStream = ftpStream.takeRetainedValue()
            setFtpUserName(for: ftpWriteStream, userName: username as CFString)
            setFtpPassword(for: ftpWriteStream, password: password as CFString)
            return ftpWriteStream
        }
    }
    
    
    // MARK: - FTP Write
    extension FTPUpload {
        public func send(data: Data, with fileName: String, success: @escaping ((Bool)->Void)) {
    
            guard let ftpWriteStream = ftpWriteStream(forFileName: fileName) else {
                success(false)
                return
            }
    
            if CFWriteStreamOpen(ftpWriteStream) == false {
                print("Could not open stream")
                success(false)
                return
            }
    
            let fileSize = data.count
            let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: fileSize)
            data.copyBytes(to: buffer, count: fileSize)
    
            defer {
                CFWriteStreamClose(ftpWriteStream)
                buffer.deallocate(capacity: fileSize)
            }
    
            var offset: Int = 0
              var dataToSendSize: Int = fileSize
    
              var shouldContinue = true
              repeat {
                  if (CFWriteStreamCanAcceptBytes(ftpWriteStream)) {
                      let bytesWritten = CFWriteStreamWrite(ftpWriteStream, &buffer[offset], dataToSendSize)
                      print("ftp bytes written: \(bytesWritten)")
                      if bytesWritten > 0 {
                          offset += bytesWritten.littleEndian
                          dataToSendSize -= bytesWritten
                          continue
                      } else if bytesWritten < 0 {
                          // ERROR
                          print("FTPUpload - ERROR")
                          shouldContinue = false
                          break
                      } else if bytesWritten == 0 {
                          // SUCCESS
                          print("FTPUpload - Completed!!")
                          shouldContinue = false
                          break
                      }
                  } else {
                      usleep(200000)
                      print(".", separator: "", terminator: "")
                  }
              } while shouldContinue
    
              success(true)
        }
    }
    
```

実行する関数は、[スタックオーバーフロー(英語版)のもの](https://stackoverflow.com/questions/46107445/ftp-
image-upload-causes-image-to-be-cut-off-swift)を参考に、以下のようにしたいのですが  
元の記事が画像をアップロードするようになっており、引数にファイルを指定する項目があります。  
JSONをファイルとして保存する方法が分かりません。

```

    func ftpuploder()
    {
    
        let ftpup = FTPUpload(baseUrl: "mysite.com", userName: "user@mysite.com", password: "password", directoryPath: "")
    
        let testJSON = {"test1":1,"test2":2}
        var JSONdata = try! JSONSerialization.data(withJSONObject: testJSON, options: JSONSerialization.WritingOptions.init())
    
        let JSON_NSData = JSONdata as Data
    
        ftpup.send(data: JSON_NSData, with: "cloudpowa.jpg", success: {(success) -> Void in
            if !success {
                print("Failed upload!")
            }
            else {
                print("image uploaded!")
            }
        })
    }
    
```

JSONをファイルとして保存したほうが良いのか  
それともファイルとして保存しなくてもFTPアップロードできるのか  
良い方法があったら教えてください。

※このコードでは短いJSONの内容になっていますが、実際には数MB程度の大きなテキストをアップロードするつもりなのでFTPを使いたいと思っています。
CC BY-SA 4.0
2020-03-11T08:30:42.767
63760
2020-03-16T03:08:26.833
36446
question
swift ios ftp
Swiftを使って、FTPでJSONファイルをアップロードしたい
ただファイルをFTPでアップロードするだけであればJSONにする必要は無いと思います。  
ファイルを用意し、FTPでアップロードの手順だと思います。  
また、すでにあるファイルがJSONファイルであれば、同様にそのままアップロード  
すればいいと思います。  
JSONをファイルとして保存する方法が分かりません。とありますが、  
何らかのファイルをJSONフォーマットに変換するという意味でしょうか？  
それであればFTPとは関係なく、特定のフォーマットのファイルを読み込み、  
それをJSONフォーマットに変換して保存することになります。  
その後、そのファイルをFTPでアップロードすることになります。

FTPのアクセスはこのようなライブラリもあるようです。  
<http://lloydsargent.github.io/BlackRaccoon/>
CC BY-SA 4.0
2020-03-11T08:52:55.387
63761
2020-03-11T08:58:30.293
2020-03-11T08:58:30.293
24490
24490
63760
answer
FTPUpload の send はアップロードしたい内容を Data型 で引数に受け取ります。  
また、 `JSONSerialization.data(...)` は受け取ったオブジェクトをJSONにして、 Data型 で返します。

なのでファイルに書き出す必要はありません。  
JSONSerializationでData型にしたものをそのまま `ftpup.send(data: ... )` に渡せば良いです。

（参考にしたStackoverflowの内容は画像ファイルを読んでJPEGのData型に変換してから送っています）
CC BY-SA 4.0
2020-03-12T05:34:54.357
63784
2020-03-16T03:08:26.833
2020-03-16T03:08:26.833
23829
23829
63760
answer