#define CFRUNLOOP_SLEEP() do { } while (0)
#define CFRUNLOOP_SLEEP_ENABLED() (0)
{"id":67,"iconImage":"image\/catalog\/style\/modile\/icons-03.png"
id имеет целочисленный тип, хотя во всех остальных местах это строка. struct EntryList: Decodable {
struct DynamicCodingKey: CodingKey {
var stringValue: String
init?(stringValue: String) { self.stringValue = stringValue }
var intValue: Int? { nil }
init?(intValue: Int) { nil }
}
struct Entry: Decodable {
struct Content: Decodable {
struct Subcategory: Decodable {
let id: String
let iconImage: String
let name: String
let sortOrder: String
let type: String
}
let iconImage: String
let iconImageActive: String
let image: String
let name: String
let sortOrder: String
let subcategories: [Subcategory]
}
let name: String
let content: Content
}
let entries: [Entry]
init(from decoder: Decoder) throws {
let entriesContainer = try decoder.container(keyedBy: DynamicCodingKey.self)
entries = try entriesContainer.allKeys.map { key in
print(key)
let content = try entriesContainer.decode(Entry.Content.self, forKey: key)
return Entry(name: key.stringValue, content: content)
}
}
}
var entryList: EntryList?
let task = URLSession
.shared
.dataTask(with: URL(string: "https://blackstarshop.ru/index.php?route=api/v1/categories")!) { (data, _, error) in
guard error == nil else { return }
guard let data = data else { return }
entryList = try! JSONDecoder().decode(EntryList.self, from: data)
}
task.resume()
enum Optional<Wrapped>: ExpressibleByNilLiteral {
// The compiler has special knowledge of Optional<Wrapped>, including the fact
// that it is an `enum` with cases named `none` and `some`.
/// The absence of a value.
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
/// Creates an instance that stores the given value.
@_transparent
public init(_ some: Wrapped) { self = .some(some) }
//...
Optional<MyClass>.some(myObj)
и тому сопутствующее... enum Optional
) сделана в виде обычного стандартного типа, Аля Int
какой-нибудь. var data = [IndexPath: String]()
и UITextFieldDelegate
. А в методе делегата сделай так:func textFieldDidEndEditing(_ textField: UITextField){
let pointInTable = textField.convert(textField.bounds.origin, to: tableView)
guard let textFieldIndexPath = tableView.indexPathForRow(at: pointInTable) else { return }
guard let text = textField.text else { return }
data[textFieldIndexPath] = data[textFieldIndexPath, default: ""] + text
}
["John", "Alpha", "Toster"]
.difference(from: ["John", "Omega", "Alpha", "Toster"])
.forEach { print($0) }
// remove(offset: 1, element: "Omega", associatedWith: nil)
class ViewController: UIViewController {
@IBOutlet var button: UIButton!
var alert: UIAlertController?
func displayActivityIndicatorAlert() {
alert = UIAlertController(title: "Deleting from black list...", message: nil, preferredStyle: .alert)
let activityIndicator = UIActivityIndicatorView(style: .medium)
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
activityIndicator.isUserInteractionEnabled = false
activityIndicator.startAnimating()
alert!.view.addSubview(activityIndicator)
alert!.view.heightAnchor.constraint(equalToConstant: 95).isActive = true
activityIndicator.centerXAnchor.constraint(equalTo: alert!.view.centerXAnchor, constant: 0).isActive = true
activityIndicator.bottomAnchor.constraint(equalTo: alert!.view.bottomAnchor, constant: -20).isActive = true
present(alert!, animated: true)
}
func dismissActivityIndicatorAlert() {
alert?.dismiss(animated: true)
alert = nil
}
var blackList = [Int](0...9)
let lock = NSLock()
func asyncDeleteBlackList() {
var tasks = [URLSessionTask]()
tasks.reserveCapacity(10)
var results = [Int: String]()
results.reserveCapacity(10)
let group = DispatchGroup()
displayActivityIndicatorAlert()
for item in blackList {
group.enter()
let url = URL(string: "https://.../api/v1/today/batch")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
// Что-то делаем с ошибкой на клиенте...
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else
{
// Что-то делаем с ошибкой на сервере...
return
}
if let mimeType = httpResponse.mimeType,
mimeType == "application/json",
let data = data,
let string = String(data: data, encoding: .utf8)
{
print("Запрос №\(item) завершён.")
self.lock.lock()
results[item] = string
self.lock.unlock()
group.leave()
}
}
tasks.append(task)
task.resume()
}
group.notify(queue: .main) {
print("\nЗадача завершена.")
self.dismissActivityIndicatorAlert()
}
}
override func viewDidLoad() {
button.addTarget(self, action: #selector(pressed(sender:)), for: .touchUpInside)
}
@objc
func pressed(sender: UIButton) {
asyncDeleteBlackList()
}
}
[
"primes": [2, 3, 5, 7, 11, 13, 15],
"triangular": [1, 3, 6, 10, 15, 21, 28],
"hexagonal": [1, 6, 15, 28, 45, 66, 91],
].sorted { $0.key < $1.key }
// [
// (key: "hexagonal", value: [1, 6, 15, 28, 45, 66, 91])
// (key: "primes", value: [2, 3, 5, 7, 11, 13, 15]),
// (key: "triangular", value: [1, 3, 6, 10, 15, 21, 28]),
// ]