2015-07-12 1 views
1

Je suis novice dans la programmation de swift et OS X. Pour mes premières étapes, j'ai voulu créer un outil de ligne de commande qui me connecte à l'interface web de mon opérateur de téléphonie mobile, puis montre la quantité de mes données laissées. J'ai commencé à écrire un emballage autour de NSURLSession pour rendre les choses plus faciles pour moi.Swift NSURLSession Les cookies NSURLRequest ne sont pas acceptés

Problème: Mon programme n'accepte pas les cookies.

J'ai essayé beaucoup de choses, en mettant aussi des politiques de cookie sur l'objet de session mais rien n'a changé. Comment puis-je faire accepter les cookies par mon programme et comment les utiliser dans des demandes ultérieures?

HttpClient.swift:

import Foundation 

class HttpClient { 

    private var url: NSURL! 
    private var session: NSURLSession 

    internal init(url: String) { 
     self.url = NSURL(string: url) 
     self.session = NSURLSession.sharedSession() 
     session.configuration.HTTPShouldSetCookies = true 
     session.configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain 
     session.configuration.HTTPCookieStorage?.cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain 
    } 

    internal func sendGet() -> String { 
     var ready = false 
     var content: String! 
     var request = NSMutableURLRequest(URL: self.url) 

     var task = session.dataTaskWithRequest(request) { 
      (data, response, error) -> Void in 
      content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String 
      ready = true 
     } 
     task.resume() 
     while !ready { 
      usleep(10) 
     } 
     if content != nil { 
      return content 
     } else { 
      return "" 
     } 
    } 

    internal func sendPost(params: String) -> String { 
     var ready = false 
     var content: String! 
     var request = NSMutableURLRequest(URL: self.url) 

     request.HTTPMethod = "POST" 
     request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") 
     request.HTTPBody = params.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false) 
     request.HTTPShouldHandleCookies = true 

     var task = session.dataTaskWithRequest(request) { 
      (data, response, error) -> Void in 
      content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String 
      ready = true 
     } 
     task.resume() 
     while !ready { 
      usleep(10) 
     } 
     if content != nil { 
      return content 
     } else { 
      return "" 
     } 
    } 

    internal func setUrl(url: String) { 
     self.url = NSURL(string: url) 
    } 
} 

main.swift

import Foundation 

let loginPage = "https://service.winsim.de/" 
let dataPage = "https://service.winsim.de/mytariff/invoice/showGprsDataUsage" 

var hc = HttpClient(url: loginPage) 
println(hc.sendPost("usernameField=username&passwordfield=password")) 
hc.setUrl(dataPage) 
println(hc.sendGet()) 

Répondre

2

problème est résolu

En fait, les cookies sont acceptés avec le code ci-dessus. J'ai essayé de me connecter à un autre site et cela a fonctionné. Aussi le login a persisté. Alors pourquoi cela n'a pas fonctionné avec le site Web de mon transporteur? Stupid me, mon opérateur a la protection CSRF et d'autres champs de formulaire cachés auxquels je n'ai pas prêté attention. Par conséquent, la connexion n'a pas fonctionné. Maintenant, je sais comment le réparer.

Pour toute personne intéressée, je posterai mon fichier HttpClient.swift mis à jour qui est un peu plus ordonné, j'espère.

N'hésitez pas à commenter mon code et donnez-moi des indices d'amélioration.

import Foundation 

public class HttpClient { 

    private var session: NSURLSession 
    private var request: NSMutableURLRequest 

    public init(url: String) { 
     self.session = NSURLSession.sharedSession() 
     session.configuration.HTTPShouldSetCookies = true 
     session.configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain 
     session.configuration.HTTPCookieStorage?.cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain 
     self.request = NSMutableURLRequest(URL: NSURL(string: url)!) 
    } 

    public func send() -> String { 
     var ready = false 
     var content: String! 

     var task = session.dataTaskWithRequest(self.request) { 
      (data, response, error) -> Void in 
      content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String 
      ready = true 
     } 
     task.resume() 
     while !ready { 
      usleep(10) 
     } 
     if content != nil { 
      return content 
     } else { 
      return "" 
     } 
    } 

    public func setUrl(url: String) -> HttpClient { 
     self.request.URL = NSURL(string: url) 
     return self 
    } 

    public func getMethod() -> String { 
     return self.request.HTTPMethod 
    } 

    public func setMethod(method: String) -> HttpClient { 
     self.request.HTTPMethod = method 
     return self 
    } 

    public func addFormData(data: Dictionary<String, String>) -> HttpClient { 
     var params: String = "" 
     var ctHeader: String? = self.request.valueForHTTPHeaderField("Content-Type") 
     let ctForm: String = "application/x-www-form-urlencoded" 

     if(data.count > 0) { 
      for(name, value) in data { 
       params += name + "=" + value + "&" 
      } 

      params = params.substringToIndex(params.endIndex.predecessor()) 
      self.request.HTTPBody = params.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false) 

      if ctHeader != nil { 
       self.request.setValue(ctForm, forHTTPHeaderField: "Content-Type") 
      } 
     } 

     return self 
    } 

    public func removeFormData() -> HttpClient { 
     self.request.setValue("text/html", forHTTPHeaderField: "Content-Type") 
     self.request.HTTPBody = "".dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false) 

     return self 
    } 
} 
+0

Hi! A travaillé parfaitement pour moi. Peut-être que vous pouvez l'améliorer en remplaçant certains caractères non autorisés comme les paramètres HTTP comme @ doit être% 40 J'ai eu peu de problème à ce sujet. Merci! – Ratinahirana

+1

ce code est erroné. Porperty 'configuration' est' readonly' et 'copy' donc ce code ne change rien. Pour modifier efficacement la configuration de la configuration de 'NSURLSession', utilisez la méthode suivante: [' NSURLSession.init (configuration de la configuration: NSURLSessionConfiguration) '] (https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#// apple_ref/occ/clm/NSURLSession/sessionWithConfiguration :). –