• Как оценить время на разработку iOS приложения аудиоплеера?

    maximglobak
    @maximglobak
    iOS developer
    Вопрос оценки сроков всегда стоит остро и придерживаюсь того, что программист оценивает задачи по своим силам и если он оценил в 100 часов, то скорее всего он и сделает за 100 часов, это его уровень. А кто-то может сделать в 10 раз быстрее и 10 раз дороже, такое тоже возможно. Плюс стоит учитывать нативность всех элементов и например, что в Андройде есть любимая шторка, то в iOS она делается кастомно и требует времени. В крупных компаниях, где уровень разработчиков примерно одинаковый, оценка задач идет примерно одинаково +-15%.
    Ответ написан
    Комментировать
  • Тестирование моб. приложения на ios?

    maximglobak
    @maximglobak
    iOS developer
    Начиная с iOS 11 система поддерживает запись экрана, вы можете составить сценарий тестирования и они могут его вручную прогонять при этом записать и отправить вам. В режиме реального времени не получится.
    Можно через тестфлайт и это достаточно хороший вариант, но есть и альтернативы. Например https://hockeyapp.net/
    Нужно добавить вас в список тестировщиков и вы будете получать новые сборки автоматически. В инструкции вы все найдете. Может так же увеличить вес приложения.
    Ответ написан
    Комментировать
  • На чем создаются нестандартные интерфейсы десктопных приложений?

    maximglobak
    @maximglobak
    iOS developer
    Еще в качестве дополнения у электрона есть конкурент nw.js, сейчас давно десктопы многие пишут на связке js + html + css, потому что основная логика находится на серверах, а десктоп выступает в качестве клиента
    Ответ написан
    Комментировать
  • Как прочитать данные из файла?

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

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

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

    maximglobak
    @maximglobak
    iOS developer
    да, ты можешь такое реализовать. Если я правильно понимаю, то в тексте у тебя надо заменить все слова "Ширина" на "Высоту"?
    Тут только математические расчеты
    Надо еще понять что у тебя в приоритете, высота ячейки Х (70) или четное количество ячеек на экране. Потому что оба условия могут не совпасть.
    1) Сначала высчитай сколько у тебя всего высот Х поместится на экране.
    maxPossibleCellsNumberOnScreen = (screenHeight - statusBarHeight) / X
    2) привязываешь в коде (autolayout) таблицу к нижней границе, а высоту таблицы = Х * ( количество ячеек )
    Но количество ячеек не должно превышать количество maxPossibleCellsNumberOnScreen - 1 (место для хедера)
    3) Привязываешь хедер от верхней границы таблицы до верхней границы экрана
    Но есть еще нюанс, если таблица скролится, и у нее идеально скрыта ячейка, то пользователь может не понять, что таблицу можно скролить.
    Ответ написан
    Комментировать
  • Кастомизация интерфейса в реальном времени?

    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 комментария
  • Как лучше делать админку для курьеров (полимер, сайт под смартфон, приложение или телеграмм)?

    maximglobak
    @maximglobak
    iOS developer
    Для таких целей хорошо подойдет React Native.
    Работает быстрее чем сайты, делаете свой дизайн, если не ошибаюсь, то можно использовать UI frameworks.
    Разработка идет сразу на две платформы + можно использовать нативные функции приложения.
    Ответ написан
  • Как в одном контроллере вызвать 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
    Ответ написан
    Комментировать