Ответы пользователя по тегу Swift
  • Почему происходит ошибка разворачивания инициализированного опционала,?

    А зачем вам здесь вообще Bool? понадобился?
    Если флаг успеха, то лучше var per2 = false.
    Ещё, у вас есть блок try-catch, но в нём ни одного try.
    Ещё, вы выводите не-развёрнутый Optional, о чём, к счастью, предупредит компилятор.
    Кроме того, у вас может произойти отказ в разных местах, так что стоит подумать над использованием ошибок / "исключений" Swift:

    func aaa() throws {
                let fetchResult = try PersistenceService.contex.fetch(fetchRequest)
    
                for item in fetchResult {
                    let per = item.password
                    guard let pass = per else {
                        throw AaaErrors.passwordNotCreated
                    }
                    print("пароль \(pass!)")
                }
        }
    Ответ написан
    Комментировать
  • Что означают A.Type и A.self, где A - некий класс, в языке Swift?

    Для любого типа T, T.Type - это метатип (metatype), то есть тип, объекты которого предоставляют описание типа T. Статические функции и init-функции T становятся функциями-членами T.Type. Пример:

    struct Duck {
        static func kind() -> String { return "Bird" }
        init() { }
        func talk() { print("Quack") }
    }
    
    let meta: Duck.Type = Duck.self
    meta.kind()  //=> Bird
    let obj: Duck = meta.init()
    obj.talk()  //=> Quack


    Существует 2 класса метатипов, но на практике встречаются existential metatypes, то есть их объекты могут описывать как данный тип T, так и любой наследник (subtype) типа T. Другими словами, множество объектов типа T.Type - это U.self для всех типов U: T. Пример:

    class Animal { class var name: String { return "Animal" } }
    class Cat: Animal { override class var name: String { return "Cat" } }
    class Dog: Animal { override class var name: String { return "Dog" } }
    
    var meta: Animal.Type
    meta = Cat.self
    meta.name  //=> Cat
    meta = Dog.self
    meta.name  //=> Dog


    Или, например, можно представить себе такую функцию генерации животных:

    class Animal { ... }
    
    func createAnimal(_ type: Animal.Type) -> Animal {
        if type == Cat.self {
            return Cat(...)
        } else if type == Dog.self {
            return Dog(...)
        } else {
            fatalError()
        }
    }


    На практике, такая функциональность метатипов используется редко. Как правило, они служат для явной специализации шаблонных функций. Например:

    func unsafeCast<T, U>(_: T, to: U.Type) -> U

    Здесь единственный способ указать тип U при вызове - это передать "фиктивный" параметр тип U.Type, так как аргументов типа U функция не принимает. Вернее, это лучший и принятый в Swift способ. Можно было бы выкрутиться вот так:

    func unsafeCast<T, U>(_: T, sameAs: U) -> U

    Но, понятно, что для этого нужно иметь под рукой объект типа U, и это не идеальный вариант. Жаль, что нельзя писать просто unsafeCast<U>(t) при вызове.

    При использовании метатипа U.Type таким образом, его значение, как правило, игнорируется. То есть даже если вы передадите туда метатип наследника типа U, то функция всё равно будет работать с U.

    P.S. Есть ещё много недокументированных фич метатипов в Swift, но там всё не очень логично и продуманно (даже разработчики из Core team не всё там понимают), так что на практике лучше ограничиться применением для явной специализации функций, как показано выше.
    Ответ написан
    1 комментарий
  • Каким спосабом обработать JSON в Swift 3?

    Подключите либу для парсинга JSON, например, раз, два, три.

    case .success:
        let json = JSON(response.result.value)
        let username: String? = json["People0"]["Name"].string
        // ...


    Обнаружилось, что передаваемый JSON был в не совсем корректном формате, из-за этого придётся делать вот так:

    case .success:
        let json = JSON(response.result.value)
        let nestedJson = JSON(parseJSON: json["People0"].string ?? "{}")
        let username: String? = nestedJson["Name"].string
        // ...
    Ответ написан
  • Нет навыков в программировании, можно ли сразу начать изучать swift?

    Swift - это отличный первый язык программирования. "База" не нужна, если вы хотите писать простенькие графические приложения. Но прежде, чем делать что-то полезное, убедитесь, что вы знаете сам Swift. Скачайте XCode. Его часть Swift Playgrounds - анимированные учебники-задания от Apple. Советую Learn to Code 1, 2, 3. Если где-то застопорились, всегда можно нагуглить гайды/подсказки/советы. Единственное, без чего нельзя начать - английский язык.
    Ответ написан
    Комментировать
  • Как решить задачу на dictionaries из книги?

    Начиная с Swift 4, следующее решение более короткое:

    func occurencesOfCharacters(in text: String) -> [Character: Int] {
      return Dictionary(text.map{ ($0, 1) }, uniquingKeysWith: { $0 + $1 })
    }
    print(occurencesOfCharacters(in: "memerr"))

    Как это работает
    В Swift 4, .characters не нужно, так как строки - это последовательности символов.
    Код text.map{ ($0, 1) } даёт последовательность вида ("m", 1), ("e", 1), ...
    Конструктор Dictionary превращает эту последовательность в словарь вида ["m": 1, "e": 1, ...].
    Когда этот конструктор встречает две пары с одинаковыми ключами, он мержит их значения по указанному правилу, по сути, подсчитывая количество вхождений данного символа.

    Замечу, что решение от DevMan, выписанное "вручную", должно работать более быстро, так как там нет промежуточного представления в виде последовательности кортежей. Но только если убрать двойное обращение к Dictionary на каждой итерации.

    Edit: Этот код должен чуть быстрее работать. Мог бы быть ещё быстрее, но увы, в Dictionary нет для этого некоторых нужных методов.
    func occurencesOfCharacters(in text: String) -> [Character: Int] {
      var dicOfChars: [Character: Int] = [:]
      for character in text.characters {
        dicOfChars[character] = (dicOfChars[character] ?? 0) + 1
      }
      return dicOfChars
    }
    print(occurencesOfCharacters(in: "memerr"))
    Ответ написан
    1 комментарий
  • Какая разница в опционалах в Swift?

    Implicitly Unwrapped Optional, в целом, ведут себя как Optional. На самом деле, они преобразовываются к Optional при каждом удобном случае:

    let x: Int! = 42
    let y = x   // y has type Int?

    Есть два отличия: во-первых, можно привести IUO к non-optional типу:

    func f(_ arg: Int) { print(arg) }
    
    let x: Int! = 42
    
    let y: Int = x
    let z = x as Int
    f(x)

    Во-вторых, можно вызывать на такой переменной методы самого объекта. Если в IUO содержится nil, то приложение упадёт с соответствующим сообщением:

    struct Dog {
        func bark() { print("Woof!") }
    }
    
    let d: Dog! = Dog()
    d.bark()

    Применяются IUO, в основном для отложенной инициализации:

    class Foo {
        var x: Int!
    
        init() {
            // I can't setup x at this point :(
            x = nil
        }
    
        func setup(x newValue: Int) { x = newValue }
    
        func foo() {
            // I promise that setupX() will be called before
            // I will deal with x as if it was always present
            print(x * 2)
        }
    }

    Замечу, что, начиная со Swift 3, IUO - это вовсе не тип, а лишь атрибут переменной, который разрешает неявные преобразования с ней. "Под капотом" всё выглядит как-то так:

    let x: Int! = 42
    @implicitlyUnwrapped let x: Optional<Int> = .some(42)
    Ответ написан
    Комментировать
  • Как изменить глобальную переменную контроллера?

    Возможно, UserService.getUsers - это асинхронная операция. В этом случае код в замыкании выполнится позже, чем код после вызова getUsers.
    Ответ написан
    1 комментарий
  • Swift или Objective-С: iOS. Книги, видеоуроки?

    Советую официальную документацию Swift Programming Language. Прочтите Language Guide от корки до корки. Копируйте и запускайте примеры, возьмите любой сборник программистких задачек (язык не важен) и решайте на Swift.
    Ответ написан
    1 комментарий
  • Json to Object на Swift (IOS)?

    Модуль для сериализации/десериализации в объект:
    https://github.com/matthewcheok/JSONCodable
    Правда, давно с ним не работал, не уверен, как там со Swift 3.
    Ответ написан
    2 комментария
  • Как достучаться до элемента classa подписанного на суб протокол?

    В Swift 3, синтаксис нескольких условий в одном if let изменился:
    if let storableProduct = prod as? Storable, storableProduct.expired == false {
        fridge.append(storableProduct)
    }

    При этом в for, while, switch по-прежнему используется where.
    Ответ написан
    Комментировать
  • Как правильно установить значение из другого класса?

    До того, как окно отобразилось, полями вашего `NSViewController` запрещено пользоваться.
    Что делать -- выполняйте изменения из какого-нибудь коллбека, например, `viewDidLoad`.
    Ответ написан
  • Как сделать зависимость координат swift?

    box.switchMove(Move) // Что??
    Move это имя типа, его нельзя тут использовать. Вот box.switchMove(Move.Left) и так далее написать можно. То есть вам нужно вычислить, в каком направлении подвинулся pers и выбрать, какой параметр передать: Move.Left, Move.Right, Move.Up или Move.Down.
    Ответ написан
    Комментировать
  • С чего стоит начать изучение swift, если раньше не сталкивался с миром программирования?

    Многие не могут представить, как можно программировать без классических навыков C/C++, Asm, Unix. Я бы сказал, что с ними действительно приходит более глубокое понимание вещей, но для того, чтобы кодить App'ы под iPhone, это не нужно. Apple продвигает свои playgrounds для быстрого обучения Swift, даже без предыдущего опыта. Посмотрите в этом направлении.
    P.S. Предупреждаю: геймдев -- не место для розовых очков :) Как правило, над играми трудятся команды, а инди-разработчику нужно потратить месяцы и годы, чтобы закончить проект.
    Ответ написан
    Комментировать
  • Как конвертировать MapKit MKCoordinateSpan в Float|Int для Google Maps?

    Если нужно просто преобразовать тип числа из Double во Float, то в Swift это выполняется с помощью конструктора:
    let coordinateSpan: MKCoordinateSpan = ...
    let latitudeFloat = Float(coordinateSpan.latitudeDelta)
    let longitudeFloat = Float(coordinateSpan.longitudeDelta)
    Ответ написан