Будет ли он вести себя как оператор if
- else
в том смысле, что вы не используете переменные вне оператора if
?
Да. Но так же, как оператор if
- else
, вы можете определить переменную перед do
- catch
:
например. в выражении if
- else
:
let foo: String
if bar > 1 {
foo = "bigger than one"
} else {
foo = "one or smaller"
}
Или, в вашем случае:
let url = URL(string: "https://www.hackingwithswift.com")!
let contents: String
do {
contents = try String(contentsOf: url)
} catch {
print(error)
return
}
let grid = contents.components(separatedBy: "\n")
Или вы ничего не делаете с сообщением об ошибке, вы можете полностью исключить do
- catch
:
guard let contents = try? String(contentsOf: url) else {
print("error")
return
}
let grid = contents.components(separatedBy: "\n")
Честно говоря, все вышесказанное, в любом случае, использование String(contentsOf:)
, вероятно, не лучший шаблон, потому что он выполняет синхронный сетевой запрос, который может привести к тому, что процесс «сторожевого таймера» ОС убьет ваше приложение бесцеремонно, если основной поток заблокирован; и даже если этого не произойдет, пользователь не сможет заморозить приложение во время выполнения сетевого запроса. Обычно мы используем URLSession
:
let url = URL(string: "https://www.hackingwithswift.com")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard
let data = data,
let httpResponse = response as? HTTPURLResponse,
let string = String(data: data, encoding: .utf8) else {
print(error ?? "Unknown error")
return
}
guard 200 ..< 300 ~= httpResponse.statusCode else {
print("Expected 2xx response, but got \(httpResponse.statusCode)")
return
}
let grid = string.components(separatedBy: "\n")
DispatchQueue.main.async {
// use `grid` here
}
}.resume()
Не связано, но:
Соглашение состоит в том, чтобы начинать имена переменных со строчных букв.
Вы реализовали loadView
. Это редко случается, и вместо этого мы внедряем viewDidLoad
, поэтому обязательно вызываем super.viewDidLoad()
.
Если вы делаете это на детской площадке, вы, очевидно, также установите needsIndefiniteExecution
, если вы еще этого не сделали.
Таким образом:
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
performRequest()
}
func performRequest() {
let url = URL(string: "https://www.hackingwithswift.com")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard
let data = data,
let httpResponse = response as? HTTPURLResponse,
let string = String(data: data, encoding: .utf8) else {
print(error ?? "Unknown error")
return
}
guard 200 ..< 300 ~= httpResponse.statusCode else {
print("Expected 2xx response, but got \(httpResponse.statusCode)")
return
}
let grid = string.components(separatedBy: "\n")
DispatchQueue.main.async {
print(grid)
// use `grid` here
}
}.resume()
}
}
PlaygroundPage.current.liveView = ViewController()
PlaygroundPage.current.needsIndefiniteExecution = true