Ответы пользователя по тегу Swift
  • Как прочитать данные из файла?

    maximglobak
    @maximglobak
    iOS developer
    Можно пойти двумя путями, использовать файлы, удобнее всего json или .plist или использовать целые БД, такие как SQL или Realm например.
    Для первого сюжета файлы обычно полностью загружаются в оперативную память (полностью считываются) и ковертируются в стандартную структуру типа словаря или массива. В таком случае ты сам методами языка достаешь случайное значение.
    Как читать файлы можно найти здесь stackoverflow.com
    Но со вторым вариантом, на мой взгляд, удобнее работать, но сложнее интегрировать, там ты уже запихиваешь все данные в базу, а в приложении подключаешься к базе и средствами базы достаешь случайные значения. Если у тебя большие данные, то лучше использовать второй вариант, но для простоты лучше использовать первый вариант.
    Ответ написан
    Комментировать
  • Как спрятать данные, находящиеся в CoreData?

    maximglobak
    @maximglobak
    iOS developer
    Один из вариантов сделать прослойку для общения со своей БД и внутри нее шифровать данные, а когда запрашиваете данные, то дешифруете обратно их.
    Можно обратить внимание на Realm БД, которая может это делать из коробки или почти из коробки.
    Ответ написан
    4 комментария
  • Правильная архитектура/шаблон model для swift-приложения?

    maximglobak
    @maximglobak
    iOS developer
    Скорее всего тебе подойдет хранение данных в БД. Не стоит бояться ее использовать. Конечно ты можешь посмотреть реализацию кэша, когда данные хранятся определенное время.
    Если бы было бы больше данных, то можно было бы сказать точнее.
    А по модели, то у нее должен быть метод получения данных (асинхронный), который в зависимости от ситуации загружает данные и сохраняет в БД и отдает тебе или просто грузит их из БД.
    Кейсов много - реализаций еще больше.
    Ответ написан
    Комментировать
  • Кастомизация интерфейса в реальном времени?

    maximglobak
    @maximglobak
    iOS developer
    Есть хорошая статья про управление цветовыми схемами в приложении.
    medium.com
    Ну если в двух словах, то у тебя должна быть функция установки цветовой схемы и при любых изменениях ты должен ее вызывать. Так же эту функцию нужно вызывать в методе viewWillAppear.
    Ответ написан
    1 комментарий
  • Как использовать .sorted для строки двумерного массива c сохранением соответствия второй строки?

    maximglobak
    @maximglobak
    iOS developer
    Написал пример для конкретного случая из двух массивов
    //: Playground - noun: a place where people can play
    
    import UIKit
    
    let input = [[5, 1, 3], [1, 2, 7]]
    let output = [[1, 3, 5], [2, 7, 1]]
    
    // ---------
    
    var result = input
    
    if let firstArray = result.first, var secondArray = result.last {
      // Сортируем первый массив
      let firstOutput = firstArray.sorted()
      // Создаем копию второго массива, которую будем изменять в процессе перестановки
      var secondOutput = secondArray
    
    
      for i in 0..<firstArray.count {
    
        // Значение элемента до сортировки
        let value = firstArray[i]
    
        // Получаем позицию после сортировки
        if let after = firstOutput.index(of: value) {
          // Записываем изменения во второй массив
          secondOutput[after] = secondArray[i]
        }
      }
    
      // Перезаписываем результат
      result = [firstOutput, secondOutput]
    
    }
    
    print(result)
    Ответ написан
    2 комментария
  • Как String массив превратить в Int массив (многомерный)?

    maximglobak
    @maximglobak
    iOS developer
    Добрый день!
    В вашем первом примере вы пытаетесь массив со строками преобразовать в Int и получаете ошибку.
    Если использовать .map, то он возвращает массив опциональными значениями. И в таком случае если попадется строка в массиве, которую невозможно будет конвертировать в Int, то в этом месте будет nil.

    Если использовать flatMap, то он оставит только те значения, которые удачно преобразовались в Int.
    let arr = [["9", "6", "7", "8", "5"], ["1", "1", "1", "1", "1"]]
    let mapArr = arr.flatMap { $0.flatMap { Int($0) } }
    Ответ написан
    3 комментария
  • Переходы из строк в UITableView к другим данным в рамках одного VC?

    maximglobak
    @maximglobak
    iOS developer
    Есть правило - разделяй и властвуй =) (S в SOLID)
    Придерживаясь этому правилу проект будет чище чем у тех, кто не придерживается.
    На первое время всегда кажется, что отдельный VC не нужен для этого, но зачастую логика позже начинает усложнятся и отличаться от того, что было на первом экране. Поэтому я советую разделить на два экрана и у тебя будут развязаны руки на дальнейшие изменения, да и код в одном VC будет чище.
    А экономия памяти, в таком случае, будет минимальным.
    Ответ написан
    Комментировать
  • Как добавить Collection View после конца прокрутки Table View?

    maximglobak
    @maximglobak
    iOS developer
    Заверни коллекцию вью в ячейку и добавь или в футер таблицы, или в футер секции, или в последнюю ячейку.
    Для этого смотри как делать кастомные ячейки и таблицы с несколькими типами ячеек.
    Ответ написан
    7 комментариев
  • Односвязный список swift, почему ошибка?

    maximglobak
    @maximglobak
    iOS developer
    1) .next не всегда обязан быть
    например для элемента (iData: 22, dData: 2.99) у тебя нет .next, но в классе говорится, что он всегда есть.
    Отсюда следует, что .next - опциональный тип
    2) Тоже самое с .first в списке, он может быть или не быть. Вдруг ты все удалил и тогда будет краш.
    3) Ошибка как раз и возникала из-за того, что пыталась взять .next, которого нет
    Ниже исправил код с комментариями.
    class Link {
      private let iData: Int
      private let dData: Double
      public var next: Link?
    
      public init(iData: Int, dData: Double) {
        self.iData = iData
        self.dData = dData
      }
    
      public func displayLink() {
        print("{\(iData), \(dData)}")
      }
    }
    
    class LinkList {
    
      private var first: Link?
    
      public func isEmpty() -> Bool {
        return first == nil
      }
    
      // INSERT
      public func insertFirst(iData: Int, dData: Double) {
        let newLink = Link(iData: iData, dData: dData)
        newLink.next = first
        first = newLink
      }
    
      // DELETE
      public func deleteFirst() -> Link? {
        // Проверяем есть ли первый элемент, иначе удалить ничего нельзя и мы возращаем nil
        guard let first = first else { return nil }
        // Если есть первый элемент, то ему присваиваем значение второго
        // Если второго нет, то ему присвоится значение nil
        // А это значит мы удалили все элементы в списке
        self.first = first.next
        return self.first
      }
    
      //Display
      public func displayList() {
        print("List (first --> last)")
        // Создаем стартовый элемент, который изначально равен первому
        // Это опциональный тип и может быть nil, так как первый элемент тоже может быть nil
        // Если вдруг мы все удалили
        var element = first
        // Потом сразу делаем проверку на nil
        // Если элемента нет, то и выводить ничего не будем
        while element != nil {
          element?.displayLink()
          element = element?.next
        }
        print("----------")
      }
    
    }
    
    
    let theList = LinkList()
    theList.insertFirst(iData: 22, dData: 2.99)
    theList.insertFirst(iData: 55, dData: 5.99)
    theList.insertFirst(iData: 77, dData: 7.99)
    
    //theList.deleteFirst()
    //theList.deleteFirst()
    //theList.deleteFirst()
    
    theList.displayList()
    Ответ написан
    1 комментарий
  • Как начать цикл for с заданного индекса в Swift 4?

    maximglobak
    @maximglobak
    iOS developer
    Можно воспользоваться старым добрым циклом for in
    // Твой массив
    let array = [0,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3]
    // Позиция, с которой стоит начать прогон по массиву
    let endPos = 5
    // Так как начало задаем сами,
    // то надо быть уверененными,
    // что endPos входит в рамки массива
    if endPos < array.count {
      // старый добрый For in
      for i in endPos..<array.count {
        // Получаем элемент из массива по индексу
        // Это очень быстрая операция, не стоит переживать из-за времени
        let item = array[i]
        // дальше совершаем какие-то действия с элементом массива
        print(item)
      }
    }
    Ответ написан
    2 комментария
  • Как в одном контроллере вызвать dealloc?

    maximglobak
    @maximglobak
    iOS developer
    Если я правильно понял тебя, то тебе нужно закрыть UIViewController изнутри?
    Если так, то можешь попробовать метод
    func dismiss(animated flag: Bool, 
      completion: (() -> Void)? = nil)

    Этот метод говорит контроллеру "закройся". Если у тебя есть navigationController, то можно вызвать метод
    navigationController?.popViewController(animated: true/false)

    В таких случаях контроллер закроется и вылетит из памяти, а при это у него вызовется метод dealloc. Конечно если у тебя нет сильной ссылки на него.
    Ответ написан
    Комментировать
  • Можно ли запустить одно приложение по клику из другого?

    maximglobak
    @maximglobak
    iOS developer
    Можно открывать другие приложения по url scheme. Выглядит это следующим образом
    guard let url = URL(string: "mail://") else { return }
    if UIApplication.shared.canOpenURL(url) {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }

    Но получить список приложений нельзя, но можно попробовать сделать запрос на каждую урл схему из популярных приложений методом
    UIApplication.shared.canOpenURL(url)
    если url можно открыть, то добавляем его в свой список приложений.
    Ответ написан
  • SWIFT, какую выбрать базу данных для хранения данных?

    maximglobak
    @maximglobak
    iOS developer
    Мне кажется если разработчик задает такой вопрос, то ему следует использовать Realm. Она будет проще для старта, да и хорошее решение в целом.
    p.s. Остальные БД надо "уметь готовить", чтоб это не приносило боль и краши =)
    Ответ написан
    Комментировать
  • Как стать IOS разработчиком без продуктов Apple?

    maximglobak
    @maximglobak
    iOS developer
    Ответ "никак" можно всегда найти на просторах гугла. Для аналогии можно привести пример обучению веб разработки, когда есть только телефон. Ну так себе, и не удобно и очень сложно.
    Но какие действительно есть варианты? Сейчас много коворкингов с маками, можно их арендовать и обучаться разработке для iOS. Проходить курсы с их железом (такие сложно найти), после которых вас, скорее всего заберет какая-то компания на стажировку. Там можно поселиться на время обучения (шутка Шредингера). Многие компании ищут iOS разработчиков и готовы инвестировать в Вас при определенных условиях. Так дайте им то, чего они хотят, а вы получите знания и опыт.
    Ответ написан
    Комментировать
  • Как написать код чтобы по нажатию на Segmentedcontrols вывести ImageView in cell TableView?

    maximglobak
    @maximglobak
    iOS developer
    Нужно составить соответствие результата всех ответов и картинок
    например я реализовал следующий вариант с enum и строковыми значениями hash значений:
    Github gist
    Ответ написан
    Комментировать
  • Как скролить экран с расположенным на нем UITableView и другими UIView?

    maximglobak
    @maximglobak
    iOS developer
    Одна из самый интересных тем для UI в iOS - табличная верстка и как ее оптимизировать =)
    каждый элемент оформляй как отдельную ячейку в таблице. Т.Е. вьюху "Заполни профиль" в отдельную ячейку, а "Скачивайте и запускайте приложение… " в отдельную с одним лейблом внутри.
    Дальше эти ячейки распихивай по разным секциям, например секции профиль, акции и футер. (не обязательно их подписывать) и потом для каждой секции и ячейки настраивай свою логику со своими reuseIdentifier и тп.
    Есть несколько страниц на эту тематику, например на Medium и так далее.
    Ответ написан
    1 комментарий
  • Как задать диапазон времени в swift3?

    maximglobak
    @maximglobak
    iOS developer
    Почему бы не посмотреть как это сделало Apple. Например похожий функционал есть календаре и у них для этого два покера (начало и конец). Можно конечно сделать один кастомные пикер для подбора двух дат, но есть ли в этом смысл? Удобно ли будет пользователю?
    Любое нестандартное решение требует объяснений. Но если совсем иначе никак, то можно сделать две кнопки через дефис и по каждому клику кнопки показывать дата пикер и потом присваивать заголовок кнопке в виде нужной даты. Тогда ячейка будет выглядеть следующим образов
    ——————
    Время проведения мероприятия (начало) - (конец)
    ——————
    После выполнения всех операций
    ——————
    Время проведения мероприятия ( 13:30 ) - ( 14:00 )
    ——————
    Кнопки отдельно лучше подсветить как кнопка "Загрузки" в новом AppStore
    Ответ написан
    1 комментарий
  • UIImage из JSON файла?

    maximglobak
    @maximglobak
    iOS developer
    Вот хороший метод
    guard let url = URL(string: movie.poster) else { return }
    DispatchQueue.global().async {
        if let data = try? Data(contentsOf: url) {
            DispatchQueue.main.async {
                posterImageView.image = UIImage(data: data)
            }
        }
    }

    Он загружает картинку асинхронно и потом выводит на экран.
    Но я бы посоветовал посмотреть в сторону библиотеки Kingfisher , она еще кэширует фотографии и тебе не придется каждый раз делать запрос в сеть, чтоб получить изображение
    Ответ написан
    2 комментария
  • Как лучше реализовать хранение текстовых данных в iOS приложении?

    maximglobak
    @maximglobak
    iOS developer
    Можно в текстовом файле (txt/json), который находится в проекте, а потом читать с него.
    Можно забирать текст с сервера и сохранять его в базу/файл.
    Можно создать отдельный хелпер с текстовыми константами.
    Посмотрите в сторону локализации, там все в "своем" файлике хранится.
    Ответ написан
    Комментировать
  • Как запустить функцию в предыдущем VC при выполнении dismiss?

    maximglobak
    @maximglobak
    iOS developer
    Можно тремя способами это сделать (можно и больше, но это как правило извращения уже).
    1) Через делагаты, можно легко найти в гугле, мне этот способ меньше всего нравится.
    2) Создать отдельный класс (мб менеджер?) Singleton, в котором будешь сохранять все нужные значение по определенной сущности
    а в первом контроллере, в методе ViewWillAppear, который вызывается каждый раз перед появлением экрана обновлять свой лейбел, данные который ты возьмешь из того самого класса-менеджера
    чаще всего такой вариант будет правильным.
    3) найти в навигейшен контроллере свой первый контроллер и ему в присвоить значение из второго контроллера.
    Т.е. при первом и втором варианте у тебя должна торчать проверти наружу, которую все могут менять, а потому в нужный момент (ViewWillAppear) обновляешь свой лебйел с этой пропертей.
    Ответ написан
    Комментировать