Делегирование частных объявленных переменных в общедоступную область - PullRequest
0 голосов
/ 10 июля 2019

У меня возникла проблема - я пытаюсь проанализировать содержимое тела html, чтобы получить доступ к необработанному тексту ответа HTML. Проблемы, с которыми я сталкиваюсь, связаны с отсутствием знаний по обработке переменных в области - например,

let _RequestPartsURL = URL(string:"http://xxxxxxx.on.ca/getData.aspx?requestType=Tech")!;
let _WebSession = URLSession.shared;
class _WebSessionCredentials {
    let _RequestURL       = _RequestPartsURL;
    let _InstancedSession = _WebSession;
    let _InstancedTask    = _WebSession.dataTask(with: _RequestPartsURL) { data,response,error in
        if error != nil {
            // Error
            print("Client Error!");
            return;
        };
        guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
            print("Server Error!");
            return;
        };
        guard let mime     = response.mimeType, mime == "text/html" else {
            print("Wrong mime type!");
            return;
        };
        var htmlbody = String(data: data!, encoding: String.Encoding.utf8)!;
        print(htmlbody.utf8)
    };
};
_WebSessionCredentials()._InstancedTask.resume();
_WebSessionCredentials()._InstancedTask.htmlbody;
 Error: Value of type 'URLSessionDataTask' has no member 'htmlbody

Когда я обращаюсь к необработанным данным, расположенным в data!, я понимаю, что переменная является локальной для let _InstancedTask, но почему доступ к данным через _WebSessionCredentials()._InstancedTask.htmlbody; неверный оператор - я не говорю, что я хотите получить доступ к htmlbody в _InstancedTask из _WebSessionCredentials()?

Я пришел из Python, поэтому я немного разбираюсь в том, как мне следует создавать экземпляры и использовать данные, расположенные в моих классах. Спасибо за помощь.

1 Ответ

0 голосов
/ 10 июля 2019

Переменная htmlbody является локальной переменной для блока URLSessionDataTask.Если вам нужен доступ к htmlbody, я бы предложил иметь htmlbody в качестве переменной экземпляра для самого класса и инициализировать его в этом блоке.Таким образом, ваш класс будет выглядеть так:

class _WebSessionCredentials {
let _RequestURL       = _RequestPartsURL
let _InstancedSession = _WebSession
var htmlbody: String?
let _InstancedTask    = _WebSession.dataTask(with: _RequestPartsURL) { [weak self] (data,response,error) in
    if error != nil {
        // Error
        print("Client Error!")
        return
    }
    guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
        print("Server Error!")
        return
    }
    guard let mime = response.mimeType, mime == "text/html" else {
        print("Wrong mime type!");
        return
    }
    self.htmlbody = String(data: data!, encoding: String.Encoding.utf8)!
    print(htmlbody.utf8)
  }
}

Теперь вы можете получить доступ к htmlbody, вызвав .htmlbody вашего _WebSessionCredentials() объекта.

Я бы предложил несколько изменений в кодечтобы быть немного более Swift-у:

class WebSessionCredentials {
    static let requestURL = URL(string:"http://xxxxxxx.on.ca/getData.aspx?requestType=Tech")!
    var htmlbody: String?
    var instancedTask: URLSessionDataTask?
    static var sharedInstance = WebSessionCredentials()

    init() {
       self.instancedTask = URLSession.shared.dataTask(with: WebSessionCredentials.requestURL) { [weak self] (data,response,error) in
        if let error = error {
            // Error
            print("Client Error: \(error.localizedDescription)")
            return
        }
        guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
            print("Server Error!")
            return
        }
        guard let mime = response.mimeType, mime == "text/html" else {
            print("Wrong mime type!");
            return
        }

        if let htmlData = data, let htmlBodyString = String(data: htmlData, encoding: .utf8) {
           self?.htmlbody = htmlBodyString
           print(htmlbody.utf8)
        }
      }
    }
}

Теперь вы можете делать то, что, как я думаю, вы изначально пытались сделать так:

WebSessionCredentials.sharedInstance.instancedTask.resume()
WebSessionCredentials.sharedInstance.htmlbody

Соглашения о присвоении имен Swift не имеютподчеркивает и следит за верблюдом.Я создал синглтон с именем sharedInstance, так как вы, казалось, дважды инициализировали _WebSessionCredentials и ожидали, что он ссылается на один и тот же объект.Глобальные переменные также не являются предпочтительными, поэтому я превратил ваш _RequestPartsURL в переменную класса с именем requestURL.Это можно получить по телефону WebSessionCredentials.requestURL.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C * [*]] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * НЕ НЕКОТОРЫЕ;В сетевом запросе, подобном тому, который у вас есть, сетевой запрос может быть выполнен, когда объект WebSessionCredentials уже освобожден.Если у вас есть strong или unowned ссылка на self, в этот момент ваше приложение будет аварийно завершено.[weak self] также гарантирует, что когда вызывается блок завершения, ваша ссылка на себя равна Optional, и вы можете безопасно получить доступ к htmlbody, позвонив по номеру self?.htmlbody.Принимая во внимание, что если бы вызов был self.htmlbody, приложение зависло бы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...