2015-10-14 78 views
4

請幫助使用SFTP連接到我的服務器,我嘗試了很多。但它沒有正常工作。服務器工作正常。使用NSURLSession不工作的SFTP

//第一種方法

let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
     let userPasswordString = "username : password" 
     let userPasswordData = userPasswordString.dataUsingEncoding(NSUTF8StringEncoding) 
     let base64EncodedCredential = userPasswordData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength) 
     let authString = "Basic \(base64EncodedCredential)" 
     config.HTTPAdditionalHeaders = ["Authorization" : authString] 
     let session = NSURLSession(configuration: config) 

     let url = NSURL(string: "sftp.myserver.com") 
     let task = session.dataTaskWithURL(url!) { 
      (let data, let response, let error) in 
      // data - nil, response - nil 
     } 

     task.resume() 

//第二種方法

func connect() { 

     let url: NSURL = NSURL(string: "sftp.myserver.com")! 
     let login:String = "username" 
     let password:String = "password" 

     let defaultCredentials: NSURLCredential = NSURLCredential(user: login, password: password, persistence: NSURLCredentialPersistence.ForSession) 

     let host: String = "myserver.com" 
     let port: Int = 22 
     let prot: String = "sftp" 


     let protectionSpace: NSURLProtectionSpace = NSURLProtectionSpace(host: host,port: port,`protocol`: prot,realm: nil,authenticationMethod: NSURLAuthenticationMethodServerTrust) 

     let credentialStorage: NSURLCredentialStorage = NSURLCredentialStorage.sharedCredentialStorage() 
     credentialStorage.setCredential(defaultCredentials, forProtectionSpace: protectionSpace) 

     let sessionConfiguration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration() 
     sessionConfiguration.URLCredentialStorage = credentialStorage 

     let session: NSURLSession = NSURLSession(configuration: sessionConfiguration) 

     let task = session.dataTaskWithURL(url, completionHandler: { data, response, _ -> Void in 

      // data- nil, response - nil 

      if let dataRRR = data, jsonResult = try! NSJSONSerialization.JSONObjectWithData(dataRRR, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary { 

       print(jsonResult) 
      } 
     }) 
     task.resume() 
    } 

//第三種方法

func heloo() { 

     let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
     let session = NSURLSession(configuration: configuration) 
     let login:String = "username" 
     let password:String = "password" 
     let params:[String: AnyObject] = [ 
      "email" : login, 
      "userPwd" : password ] 

     let url = NSURL(string:"sftp.myserver.com") 
     let request = NSMutableURLRequest(URL: url!) 
     request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") 
     request.HTTPMethod = "POST" 

     request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions(rawValue: 0)) 

     let task = session.dataTaskWithRequest(request) { 
      data, response, error in 

      // data - nil, response - nil 

      if let dataRRR = data, jsonResult = try! NSJSONSerialization.JSONObjectWithData(dataRRR, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary { 

       print(jsonResult) 
      } 

     } 
     task.resume() 

    } 

當我加載這個 「sftp.myserver.com」 在瀏覽器,我得到這樣的登錄表單。 enter image description here

+0

如果您的網址不是「SFTP://sftp.myserver.com」,以便它可以計算出使用的協議? –

+1

如果你想隱藏你的服務器地址,你失敗了。 –

回答

1

NSURLSession文檔:

的NSURLSession類本身支持的數據,文件,FTP,HTTP, 和https URL方案,與代理服務器和 SOCKS網關透明支持體,如在配置用戶的系統偏好。您還可以添加對您自己的自定義網絡協議和URL 方案的支持(用於您的應用程序的私人使用)。

不支持sftp方案。

+0

沒有* native *支持。你可以通過像[NMSSH](https://github.com/NMSSH/NMSSH)這樣的庫來獲得它, – Iree

1

問題是你沒有實現NSURLSession的質詢處理程序。我刺傷了這個,我能夠得到auth提示符。

完整的代碼如下。該代碼段提供一個提示提示來獲取用戶憑證;如果您在之前知道手中的證書並且不想提示,那麼您可以硬編碼您的憑證而不是提示提示;

class ViewController: UIViewController,NSURLSessionDelegate,NSURLSessionTaskDelegate { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.startConnection() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func startConnection() { 
     let END_POINT_URL = "http://sftp.dewdrive.com:80"; 
     let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
     let session = NSURLSession(configuration: config,delegate: self,delegateQueue: nil) 

     let url = NSURL(string: END_POINT_URL) 
     let task = session.dataTaskWithURL(url!) { 
      (let data, let response, let error) in 
      // data - nil, response - nil 
     } 

     task.resume() 

    } 

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { 

     let authMethod = challenge.protectionSpace.authenticationMethod; 

     if authMethod == NSURLAuthenticationMethodServerTrust { 

      let credential = NSURLCredential(trust: challenge.protectionSpace.serverTrust!); 
      let disposition = NSURLSessionAuthChallengeDisposition.UseCredential; 
      completionHandler(disposition,credential); 

     } else if authMethod == NSURLAuthenticationMethodDefault || authMethod == NSURLAuthenticationMethodHTTPBasic || authMethod == NSURLAuthenticationMethodNTLM { 

      let server = challenge.protectionSpace.host; 
      let alert = UIAlertController(title: "Authentication Required", message: "The Server \(server) requires username and password", preferredStyle: UIAlertControllerStyle.Alert); 


      alert.addTextFieldWithConfigurationHandler({ (textField:UITextField) -> Void in 
       textField.placeholder = "User Name"; 
      }) 
      alert.addTextFieldWithConfigurationHandler({ (txtField) -> Void in 
       txtField.placeholder = "Password"; 
       txtField.secureTextEntry = true; 
      }) 

      alert.addAction(UIAlertAction(title: "Log In", style: UIAlertActionStyle.Default, handler: { (action) -> Void in 
       let username = alert.textFields?.first?.text; 
       let pwd = alert.textFields?.last?.text 

       let credential = NSURLCredential(user: username!, password: pwd!, persistence:NSURLCredentialPersistence.ForSession); 

       completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential,credential); 


      })) 

      alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (action) -> Void in 
       completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge,nil); 

      })) 

      dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       self.presentViewController(alert, animated: true, completion: {() -> Void in 

       }); 

      }) 

     } 
    } 
} 

希望這有助於;快樂的編碼。

編輯:如果你有興趣在檢查出的工作副本,發現它here