2015-07-12 3 views
1

Я новичок в программировании Quick и OS X. Для моих первых шагов я хотел создать инструмент командной строки, который регистрирует меня в веб-интерфейсе моего мобильного оператора, а затем показывает количество моих данных. Я начал писать обертку вокруг NSURLSession, чтобы облегчить мне работу.Swift NSURLSession NSURLRequest Cookies не принимаются

Проблема: Моя программа не принимает cookies.

Я пробовал много вещей, также устанавливая политики cookie для объекта сеанса, но ничего не изменилось. Как я могу заставить свою программу принимать файлы cookie и как их использовать в последующих запросах?

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()) 

ответ

2

Проблема решается

В самом деле, печенье принимаются с приведенным выше кодом. Я попытался войти на другой сайт, и он сработал. Кроме того, логин сохранялся. Так почему это не сработало с сайтом моего оператора?

Глупый я, мой перевозчик имеет защиту CSRF и другие скрытые поля формы, на которые я не обращал внимания. Следовательно, логин не работает. Теперь я знаю, как это исправить.

Для всех, кого это интересует, я буду размещать обновленный файл HttpClient.swift, который является немного более аккуратным, я надеюсь.

Пожалуйста, не стесняйтесь прокомментировать мой код и дать мне подсказки для улучшения.

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! Работал идеально для меня. Возможно, вы можете улучшить его, заменив некоторый неавторизованный символ, поскольку параметры HTTP, такие как @, должны быть% 40. У меня было мало проблем. Спасибо! – Ratinahirana

+1

этот код является неправильным. Конфигурация Porperty '' readonly' и 'copy', поэтому этот код ничего не меняет. Чтобы эффективно изменить конфигурацию «NSURLSession», используйте следующий метод: ['NSURLSession.init (конфигурация конфигурации: NSURLSessionConfiguration)'] (https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#// apple_ref/ОКК/CLM/NSURLSession/sessionWithConfiguration :). –

 Смежные вопросы

  • Нет связанных вопросов^_^