0

私のMac OS X Cocoaアプリでは、しようとしています

  • ユーザー名/パスワード資格情報のみを受け入れる SFTP サーバーに接続する
  • リモート ディレクトリの内容を取得する
  • ファイルをアップロードする

驚くほど複雑です。

ConnectionKit (ほとんどドキュメントがない)、NMSSH (同時アップロードで頻繁にクラッシュする)、rsync (サーバーでサポートされていない)、sftp (スクリプト化されている場合はキー認証が必要、ユーザー名/パスワードでは機能しない) を試した後、私は今ConnectionKit に戻る: https://github.com/karelia/ConnectionKit

ただし、デリゲート メソッドで自分の資格情報をどう処理すればよいかわからないため、認証の課題に苦労しています。

  • ConnectionKit (明らかにバージョン 2) をダウンロードしてコンパイルしました。
  • Readmeが示すように、CK2FileManager を使用しようとしています (これは正しいアプローチですか? それとも、代わりにlibssh2_sftp-Cocoa-wrapperを使用する必要がありますか?... ただし、以前は NMSSH で libssh2 ブロッキング メソッドに問題がありました)。
  • 接続 URL を正常にセットアップしています。
  • 私のデリゲートの -didReceiveAuthenticationChallenge が呼び出されます

しかし、これは私が苦労しているところです: NSURLCredential を作成する方法は知っていますが、それをどうするかわかりません =>

- (void)fileManager:(CK2FileManager *)manager
 didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{
  NSURLCredential *credentials = [NSURLCredential 
    credentialWithUser:self.username
    password:[self getPassword]
    persistence:NSURLCredentialPersistenceForSession];

    // what to do now?
    // [manager useCredential:] doesn’t exist, nor is there a manager.connection?
    // ...
}

私はすでにヘッダーを読み、このリストのアーカイブを検索しましたが、すべての回答が古くなっているようです. Google、Bing、StackOverflow も検索したところ、現在のフレームワークには含まれていないように見える CKFTPConnection を使用した 2011 年の有望な例が 1 つ見つかりました。

正しい方向へのポインタをありがとう。


tl;dr

ConnectionKit の CK2FileManager authenticationChallenge への応答方法がわかりません: コード例のコメントを参照してください

4

2 に答える 2

3

CK2 の場合:

- (void)listDirectoryAtPath:(NSString *)path
{
    // path is here   @"download"
    NSURL *ftpServer = [NSURL URLWithString:@"sftp://companyname.topLevelDomain"];
    NSURL *directory = [CK2FileManager URLWithPath:path isDirectory:YES hostURL:ftpServer];

    CK2FileManager *fileManager = [[CK2FileManager alloc] init];
    fileManager.delegate = self;

    [fileManager contentsOfDirectoryAtURL:directory
               includingPropertiesForKeys:nil
                                  options:NSDirectoryEnumerationSkipsHiddenFiles
                        completionHandler:^(NSArray *contents, NSError *error) {
                            if (!error) {
                                NSLog(@"%@", contents);
                            } else {
                                NSLog(@"ERROR: %@", error.localizedDescription);
                            }
                        }];

}

そして、次のプロトコルを実装する必要があります

- (void)fileManager:(CK2FileManager *)manager operation:(CK2FileOperation *)operation
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(CK2AuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
    if (![challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodDefault]) {
        completionHandler(CK2AuthChallengePerformDefaultHandling, nil);
        return;
    }

    NSString * username = @"<username>";
    NSString * pathToPrivateSSHKey = @"</Users/myNameOnLocalMaschine/.ssh/id_rsa>"

    NSURLCredential *cred = [NSURLCredential ck2_credentialWithUser:username
                                                       publicKeyURL:nil
                                                      privateKeyURL:[NSURL fileURLWithPath:pathToPrivateSSHKey]
                                                           password:nil
                                                        persistence:NSURLCredentialPersistenceForSession];
    completionHandler(CK2AuthChallengeUseCredential, cred);

}

それでおしまい。

を呼び出す-listDirectoryAtPath:と、指定されたパスにあるすべてのファイルが content 配列の Completion Handler Block に取得されます:)

于 2014-01-18T00:36:26.470 に答える