iOS: SFTP, SCPでファイルアップロード

- Swift 5
- Xcode Version 12.3
- NMSSH


iOSアプリ開発にて、SFTPでサーバーにファイルをアップロードする仕様でした。
今回使用したライブラリは[NMSSH](https://github.com/NMSSH/NMSSH)。これ以外、見つけられませんでした。
- https://github.com/NMSSH/NMSSH


## CocoaPodのインストール
まずはここでつまづきました。
参照）https://qiita.com/spring_i/items/181bc3c05142d1f80d93

```bash
$ sudo gem install -v1.8.4 cocoapods -n /usr/local/bin
$ pod setup
```

## MNSSHのインストール

Xcodeのプロジェクトは作成済みとしています。

```
$ cd [プロジェクト名]
$ pod init
```

Podfileが生成されますので、それを編集。

```bash:Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SampleProject' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for GSApp
  pod 'NMSSH'
end
```
インストールコマンド

```bash
$ pod install
```

## ライブラリインポート

プロジェクトを、生成された**[プロジェクト名].xcworkspace**をダブルクリックして起動する。

対象のファイルにて、ライブラリインポート

```swift:ViewController.swift
imprt NMSSH
```

## アップロードするダミーファイル作成

アップロードするためのダミーファイル作成

```swift:ViewController.swift
        do {
            let fileManager = FileManager.default
            let doc = try fileManager.url(for: .documentDirectory,
                                          in: .userDomainMask,
                                          appropriateFor: nil, create: false)
            let path = doc.appendingPathComponent("muyFile.txt")
            let data = "Hello, world".data(using: .utf8)
            fileManager.createFile(atPath: path.path, contents: data, attributes: nil)
        } catch {
            print(error)
        }
```

## アップロード(SCP)

```swift:ViewController.swift
            let host = "[IPアドレス]"
            let username = "[ユーザー名]"
            let password = "[パスワード]"
            let remotePath = "[送信先のファイルパス]"
            let session = NMSSHSession.connect(toHost: host, withUsername: username)
            if (session.isConnected) {
                session.authenticate(byPassword: password)
                if (session.isAuthorized) {
                    session.channel.uploadFile(path.path, to: remotePath)
                }
            }
            session.disconnect()
```

## アップロード(SFTP)

```swift:ViewController.swift
            let host = "[IPアドレス]"
            let username = "[ユーザー名]"
            let password = "[パスワード]"
            let remotePath = "[送信先のファイルパス]"
            let session = NMSSHSession.connect(toHost: host, withUsername: username)
            if (session.isConnected) {
                session.authenticate(byPassword: password)
                if (session.isAuthorized) {
                    session.sftp.connect()
                    do {
                        let data = try Data(contentsOf: URL(fileURLWithPath: path.path))
                        session.sftp.writeContents(data, toFileAtPath: remotePath)
                    } catch {
                    }
                }
            }
            session.disconnect()
```

## サンプルソースコード(SCP)

onClickをボタンと結びつけています。

```swift:ViewController.swift
//
//  ViewController.swift
//  SampleProject
//
//  Created by SankoSC on 2020/12/21.
//

import UIKit
import NMSSH

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func onClick(_ sender: Any) {
        sftp()
    }
        
    func sftp() {
        do {
            let fileManager = FileManager.default
            let doc = try fileManager.url(for: .documentDirectory,
                                          in: .userDomainMask,
                                          appropriateFor: nil, create: false)
            let path = doc.appendingPathComponent("muyFile.txt")
            let data = "Hello, world".data(using: .utf8)
            fileManager.createFile(atPath: path.path, contents: data, attributes: nil)
        
            let host = "[IPアドレス]"
            let username = "[ユーザー名]"
            let password = "[パスワード]"
            let remotePath = "[送信先のファイルパス]"
            let session = NMSSHSession.connect(toHost: host, withUsername: username)
            if (session.isConnected) {
                session.authenticate(byPassword: password)
                if (session.isAuthorized) {
                    session.channel.uploadFile(path.path, to: remotePath)
                }
            }
            session.disconnect()
        } catch {
            print(error)
        }
    }
}
```

## API Documents

- http://cocoadocs.org/docsets/NMSSH/2.2.7/index.html
- http://cocoadocs.org/docsets/NMSSH/2.2.7/Classes/NMSSHSession.html
- http://cocoadocs.org/docsets/NMSSH/2.2.7/Classes/NMSFTP.html
- http://cocoadocs.org/docsets/NMSSH/2.2.7/Classes/NMSSHChannel.html