Kotlin/Swift (iOS) Туда и Обратно
36 subscribers
130 photos
21 videos
9 files
88 links
Канал - журнал, рассказывающий об опыте изучения Swift & iOS backend-разработчиком на Java & Kotlin
Download Telegram
Если кто-то проходит этот же курс, или будете рекомендовать его друзьям, не забудьте выделить важность Optional статей, они не содержат видео и небольшие по объему. Несмотря на то, что они подаются как оциональные - материал действительно стоящий внимания.

Отдельно подчеркну, что наличие текста под каждым видео невероятно полезно! Это позволяет воспользоваться поиском, скопировать листинги показанные на видео, или же воспользоваться переводчиком и лучше понять, то о чем рассказывает автор.

#hackingwithswift
👍2
➡️Day 10: Structs, computed properties, and property observers

Это очень круто! Пока мне не понятно в чём существенное отличие struct & class (об этом будет потом). Но подход к mutable/immutable объектам (если они называются объектами, наверное, точнее будет определение экземпляр структуры) домонстрирует совершенно новый для меня подход.

📼 mutating func
В примере автора демонстрируется mutating func и запрет компилятора на вызов такого метода, если переменная объявлена с модификатором let.
Если опустить mutating, компилятор нам укажет, что нельзя модифицировать vacationRemaining, несмотря на то, что переменная содержит модификатор var


struct Employee {
let name: String
var vacationRemaining: Int

mutating func takeVacation(days: Int) {
if vacationRemaining > days {
vacationRemaining -= days
print("I'm going on vacation!")
print("Days remaining: \(vacationRemaining)")
} else {
print("Oops! There aren't enough days remaining.")
}
}
}

let employee = Employee.init(name: "Person", vacationRemaining: 10)
employee.takeVacation(days: 5) // не будет работать, т.к. employee объявлен как let


📼 Вычисляемые поля работают похожим образом как и в Kotlin. Думаю, что это тоже вполне распространённая возможность современных языков, но могу ошибаться!


var vacationRemaining: Int {
get {
vacationAllocated - vacationTaken
}
set {
vacationAllocated = vacationTaken + newValue
}
}


📼 init и self
init это аналог constructor в Kotlin. Позволяет задать явный конструктор с различным набором параметров.
С self тоже всё довольно таки просто - это аналог this в Java & Kotlin. Если название поля совпадает с именем параметра, то self позволит их отличить.

📼 Наблюдатели свойства (property observers)

struct App {
var age: Int = 0 {
willSet {
print("Возраст скоро изменится на \(newValue)")
}
didSet {
print("Возраст изменился с \(oldValue) на \(age)")
}
}
}

Данная вещь позволяет выполнить код перед и после изменения поля. Не припоминаю, чтобы в Kotlin было что-то подобное на уровне языка, но это можно достичь с помощью AOP (Aspect-oriented programming). Пока не уверен, что это что-то полезное, но может при работе с UI это пригодится. Берём на вооружение!

#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Очень объемный урок 😰
Похоже следующие меньше не будут…
Please open Telegram to view this post
VIEW IN TELEGRAM
👨‍💻3🔥1
Всем привет, сегодня будет последний день, за который я планирую закончить оставшиеся из 14 уроков 💪

➡️Day 11: Access control, static properties and methods, and checkpoint 6

Модификаторы доступа всегда вызывают у меня смешанные чувства. Я отношусь к ним скептически. Пока у меня складывается ощущение, что мне не придётся писать сложную иерархию классов, а поэтому я буду ограничен только использованием этих модификаторов в библиотечных классах.

Статические поля и методы, они и в Африке статические

➡️Day 12: Classes, inheritance, and checkpoint 7

Изначально я ожидал, что это будет большая тема, но зная что такое struct понимание class существенно упрощается.
В целом классы в Swift очень похожи на классические классы ООП. Тут есть практически всё, что есть в struct, но в дополнение идёт наследование, отсутствие автоматических init методов для полей, и пожалуй самое интересное: объекты передаются по ссылке. Рассмотрим пример:


class User {
var username = “Ivan”
}

let user1 = User()
let user2 = user1

print(user1.username) // Ivan
print(user2.username) // Ivan

user2.username = “Petr”

print(user1.username) // Petr
print(user2.username) // Petr


Несмотря на то, что обе переменные объявлены с помощью let, поля могут быть изменены. Изменение user2.username меняет так же user1.username.
В случае использования struct User, нам нужно будет изменить var user2 = user1, чтобы была возможность изменить поле username. И что самое отличительное тут, это изменение user2.username не влечёт изменение user1.username. Насколько я понимаю, в какой-то момент создаётся копия экземпляра.

Также есть тонкости с тем, когда Swift удаляет ненужные объекты. Но это отдельный топик требующий внимания #todo

#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Финишная прямая 🏁🏎

➡️Day 13: Protocols, extensions, and checkpoint 8

Протоколы это что-то вроде интерфейсов в Java/Kotlin. И struct и class могут реализовывать протоколы. В целом, можно использовать как я привык это делать, но до тех пор пока не потребуется что-то делать с типом Self и (или) associatedtype.

Насколько я понял, это тип будущей реализации протокола (как в случае с Self) или же какой-то тип, который будет определён в реализации протокола (как в случае с associatedtype). Выглядит как продвинутые фишки, но полезны они, скорее всего, авторам библиотек. #todo хочется изучить этот концепт более детально!

К слову, в Kotlin это достигается с помощью шаблонов (generics), но возможно есть ключевые отличия. И я жду, когда же в Swift я увижу generics? 🤔
var arr = [[String]]() не в счёт 🤣

Extensions
Так же присутствуют в Kotlin. Возможность добавить новый функционал для уже существующих protocol, struct, class.
Кстати, это и механизм для создания дефолтной реализации метода в протоколе. В Java/Kotlin это можно сделать напрямую в определении интерфейса.

Хоть меня сложно испугать типами, после того как я осилил Higher-Kinded Types в Scala 👩‍💻, Self, associatedtype, type erasure, some, any заставляют извилины пошевелиться вновь 🧠

#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
➡️Day 14: Optionals, nil coalescing, and checkpoint 9

Концепция опциональных (nullable) типов давно не нова, изначально это были различные обёртки (очень современно в Java, они там есть до сих пор, называется Optional), потом, если не ошибаюсь, C# ввели синтаксис вида Type?.
На мой взгляд это лаконично и элегантно - отличное решение авторов Swift & Kotlin переиспользовать это 👍

Я нашёл любопытной подход guard, когда мы делаем проверку входящих параметров:

func printSquare(of number: Int?) {
guard let number = number else {
print("Missing input")

// 1: We *must* exit the function here
return
}

// 2: `number` is still available outside of `guard`
print("\(number) x \(number) is \(number * number)")
}

Возможно это ничем не лучше

if let unwrappedNumber = number {
printSquare(of: unwrappedNumber)
}

Но позволяет перенести “распаковку” опционального типа внутрь функции. Особенно если эта функция вызывается часто.
Наедюсь во время создания приложения встретить случай когда эта конструкция окажется полезной.

Оператор объединения с nil

Данная конструкция присутствует и в Kotlin, но там она выглядит интереснее - Элвис оператор ?:
Наклоните голову налево и поймете почему он так называется 😋

optional try

Классно! Просто классно!

do {
let result = try runRiskyFunction()
print(result)
} catch {
// it failed!
}

можно переписать как

if let result = try? runRiskyFunction() {
print(result)
}

но так в случае если ошибка совсем не важна.

#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Вот и всё! Основы Swift в кармане, и я готов погружаться в SwiftUI 👶

Дальше, скорее всего, будет много кода, и меня немного смущает, как Telegram отображает сниппеты. Например, нет нумерации строк, что не очень удобно.

Поэтому я думаю, как лучше оформить код в постах. Основное внимание будет на скриншотах приложений, но я также хочу делиться самим кодом.

Вот какие варианты я рассматриваю:
🟢Создавать проекты на GitHub 👩‍💻 - но чтение кода через GitHub может быть неудобным по сравнению с Telegram.
🟢Использовать GitHub Gist - это сниппеты кода в GitHub, но как это будет смотреться в Telegram, не уверен.
🟢Использовать страницы в Telegraph - они открываются прямо в Telegram, но пока не понятно, как будет выглядеть форматирование кода.
🟢Продолжить использовать стандартные Telegram-сниппеты - но мне не нравится, как это выглядит с большим количеством кода.
🟢Прикреплять код как изображения - возможно, так будет проще для восприятия, но зумить и искать по ним не получится

Если у кого-то есть идеи по этому вопросу - буду рад, если вы поделитесь! 😇
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🤔1
Нууу.. начинаем 🔢 👶
Первым проектом будет приложения для разделения счёта в кафе/ресторане
Проект состоит из 3х частей, попробую осилить за один день
https://www.hackingwithswift.com/100/swiftui/16

#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1👏1
За сегодняшний день я прошёл всё, что запланировал (нужны ли ссылки на уроки?)
🟢Day 16 – Project 1, part one
🟢Day 17 – Project 1, part two
🟢Day 18 – Project 1, part three
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
В конечном итоге у меня получилось приложение такого вида
Это приложение по своей сути является калькулятором, позволяющим разделить определенную сумму и чаевые на указанное количество человек поровну
👍1
WeSplit.png
4 MB
Попробую скинуть код в таком формате. Telegram сохраняет качество, если отправлять как файл
👍1
И ещё продублирую кодом, а вы можете полайкать тот вариант, который больше нравится

import SwiftUI

struct ContentView: View {
@State private var totalAmount: Double = 0.0
@State private var numberOfPeople: Int = 2
@State private var tipPercentage: Int = 15
@FocusState private var isKeyboardFocused: Bool

private var amountPerPerson: Double {
return amountWithTips / Double(numberOfPeople)
}
private var amountWithTips: Double {
return totalAmount * (1 + Double(tipPercentage) / 100.0)
}

var body: some View {
NavigationView {
Form {
Section {
TextField("Amount", value: $totalAmount, format: .currency(code: "USD"))
.keyboardType(.decimalPad)
.focused($isKeyboardFocused)
Picker("Number of people", selection: $numberOfPeople) {
ForEach(2...20, id: \.self) {
Text("\($0) people")
}
}
}
Section("Tips") {
Picker("Tips size", selection: $tipPercentage) {
ForEach(0...100, id: \.self) {
Text($0, format: .percent)
}
}
.pickerStyle(.navigationLink)
}
Section("Amount per persion") {
Text(amountPerPerson, format: .currency(code: "USD"))
}
Section("Total") {
Text(amountWithTips, format: .currency(code: "USD"))
}
}
.navigationTitle("WeSplit")
.toolbar {
if isKeyboardFocused {
Button("Done") {
isKeyboardFocused = false
}
}
}
}
}
}
👍3
Что я узнал за эти уроки?
🟢NavigationView, Form, Section — базовые элементы для построения интерфейса.
🟢Safe Area — SwiftUI по умолчанию ограничивает рабочую область, чтобы интерфейс корректно отображался с вырезами на новых моделях iPhone (чёлка, строка статуса и т. д.).
🟢 Работа кнопок и изменение переменных через них.
🟢 @State - хитрая вещь, позволяет изменять переменные внутри struct
🟢 Привязка View и Model через $ перед именем переменной.
🟢 Ввод пользователя и работа с текстовыми полями.
🟢 Базовые принципы навигации в приложении.
🟢 Вычисляемые свойства.
🟢 @Focus управление видимостью элементов (например, клавиатуры).

Впечатления

Мне нравится подача материала: видео короткие, по делу, с полезными наблюдениями. Автор плавно усложняет темы, показывая новые концепции на основе уже изученных. Есть вещи, которые пока не до конца понятны, но это нормально — SwiftUI невозможно понять за пару уроков. Интересно разобраться, как он устроен под капотом (а может, и не стоит 🤔).

Отдельно отмечу внимание к деталям. Автор объясняет важность доступности (Accessibility), например, почему текстовые поля, даже если они не видны, нужны для экранных озвучивателей, помогающих слабовидящим пользователям.

So far, so good! А как вам
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Попробовал создать “пустое” приложение на Android, по типу “Hello World”. При первом запуске получил такое… Что называется встречают с караваем 🤣🤣
👍2😢1
Со второго раза запустилось 😎

В будущем хочу попробовать написать одно из учебных приложений (которые напишу под iOS) под Android без прохождения курса — просто опираясь на свой опыт и документацию. Интересно, насколько это получится и какие подводные камни встретятся по пути 🥸 Предвкушаю будет не просто

Напомню, что несмотря на то, что у меня много опыта с Kotlin, в Android я почти 0️⃣
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
В конце первого проекта автор подготовил тест для самопроверки
Делюсь с вами моим весьма отличным результатом 💪
https://www.hackingwithswift.com/review/ios-swiftui/wesplit
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Используя ChatGPT мне удалось реализовать такое вот приложение.
Оно позволяет сохранять фото, название, описание, оценку какого либо предмета или товара. Довольно таки простое по функционалу (мне даже удивительно, что ничего подобного не нашёл в AppStore 🅰️), но для меня оказалось очень полезным 😌 Поиск я так и не реализовал, но всё впереди

Дизайн приложения мне и самому не нравится 😅, а вот с технологической точки зрения, тут есть возможность добавлять категории, присутствует сортировка по рейтингу, используется Core Data для хранения сущностей
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2