Начало положено! 🔥
Вчерашний день стал отличным стартом моего пути в изучении Swift👉
Вместо заслуженного отдыха после напряжённой рабочей недели я решил посвятить вечер саморазвитию. Прошёл вводное видео и три урока:
➡️ Day 1: Variables, constants, strings, and numbers
➡️ Day 2: Booleans, string interpolation, and checkpoint 1
➡️ Day 3: Arrays, dictionaries, sets, and enums
Общее впечатление от уроков5️⃣ ➕
Курс отлично оформлен, материал подаётся доступно, с чёткими примерами, что особенно важно для новичков.
💡 Что понравилось:
🟢 Чёткая структура: каждый урок сопровождается текстом, дублирующим содержание видео. Это здорово экономит время, когда нужно быстро освежить материал.
🟢 Наглядность: примеры простые, но при этом хорошо раскрывают суть тем.
⚠️ Что можно улучшить:
Тесты, которые добавил автор, они помогают проверить усвоение урока, но есть большое НО, тесты мне показались не очень полезными, тк они одинаковые. Да-да, 6 задач в тесте, и все они как близнецы. Возможно в дальнейших уроках тесты будут более полезными.
🛠 Для меня из этих 3 уроков, самым полезным была демонстрация синтаксиса определения массива (array) и словарь (dictionary), а так же возможность компилятора понимать тип и опускать название класса как в этом примере
Надеюсь, следующие уроки не разочаруют! 🤞🍀
Вчерашний день стал отличным стартом моего пути в изучении Swift
Вместо заслуженного отдыха после напряжённой рабочей недели я решил посвятить вечер саморазвитию. Прошёл вводное видео и три урока:
Общее впечатление от уроков
Курс отлично оформлен, материал подаётся доступно, с чёткими примерами, что особенно важно для новичков.
Тесты, которые добавил автор, они помогают проверить усвоение урока, но есть большое НО, тесты мне показались не очень полезными, тк они одинаковые. Да-да, 6 задач в тесте, и все они как близнецы. Возможно в дальнейших уроках тесты будут более полезными.
enum Weekday {
case monday, tuesday, wednesday, thursday, friday
}
var day = Weekday.monday
day = .tuesday
day = .friday
Надеюсь, следующие уроки не разочаруют! 🤞🍀
Please open Telegram to view this post
VIEW IN TELEGRAM
Hacking with Swift
Day 1 – 100 Days of SwiftUI
Follow the 100 Days of SwiftUI and learn to build apps for free.
🔥1🙏1
Я занимаюсь решением задач на Leetcode 👩💻 уже два года. За это время я освоил основные подходы к решению таких задач.
В какой-то момент мне казалось, что они имеют мало общего с теми, которые я решаю на работе. Однако это впечатление оказалось ошибочным🛑
Через несколько месяцев я заметил, что решения, которые я нахожу для повседневных задач, начинают автоматически оптимизироваться — изменился сам подход к решению.
При этом важно понимать, что оптимизация не всегда имеет решающее значение, но если несколько решений одинаковы по трудозатратам, почему бы не выбрать наиболее эффективное?
Если архитектура решения продумана, а все его части оптимизированы, то на выходе получится (если не вдаваться в детали) почти оптимальный продукт.
Сегодня я впервые решил задачу на Leetcode👩💻 с использованием Swift 🗺 . В ближайшее время напишу пост об этом… ✍️
#leetcode
В какой-то момент мне казалось, что они имеют мало общего с теми, которые я решаю на работе. Однако это впечатление оказалось ошибочным
Через несколько месяцев я заметил, что решения, которые я нахожу для повседневных задач, начинают автоматически оптимизироваться — изменился сам подход к решению.
При этом важно понимать, что оптимизация не всегда имеет решающее значение, но если несколько решений одинаковы по трудозатратам, почему бы не выбрать наиболее эффективное?
Если архитектура решения продумана, а все его части оптимизированы, то на выходе получится (если не вдаваться в детали) почти оптимальный продукт.
Сегодня я впервые решил задачу на Leetcode
#leetcode
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Сегодняшняя задача: https://leetcode.com/problems/map-of-highest-peak/
1765. Map of Highest Peak - нужно построить сушу с самыми высокими холмами, где высота в каждой клетке отличается от соседних не более чем на 1. Изначально клетка = 1 обозначает воду, а клетка = 0 сушу. При ответе высота воды обозначается 0.
Решение:
Я использую BFS (поиск в ширину), который реализуется с помощью структуры данных Queue. При реализации я активно пользовался Google, т.к. для меня оказалось трудностью элементарное использование
Некоторые интересные моменты, которые я подметил для себя:
🟢
🟢
🟢
🟢 🤔
Маленькая задача, а сколько открытий! Предвкушаю, что меня ждёт дальше в изучении Swift🥸
#leetcode
1765. Map of Highest Peak - нужно построить сушу с самыми высокими холмами, где высота в каждой клетке отличается от соседних не более чем на 1. Изначально клетка = 1 обозначает воду, а клетка = 0 сушу. При ответе высота воды обозначается 0.
Решение:
class Solution {
func highestPeak(_ isWater: [[Int]]) -> [[Int]] {
let m = isWater.count
let n = isWater.first!.count
var mutableIsWater = isWater
var queue = Deque<(Int, Int)>()
for i in 0..<m {
for j in 0..<n {
if isWater[i][j] == 1 {
queue.append((i, j))
isWaterMutable[i][j] = 0
} else {
isWaterMutable[i][j] = -1
}
}
}
let directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
var currentHeight = 1
while !queue.isEmpty {
let layerSize = queue.count
for _ in 0..<layerSize {
let (i, j) = queue.popFirst()!
directions.forEach { direction in
let x = i + direction.0
let y = j + direction.1
if x >= 0 && x < m && y >= 0 && y < n {
if isWaterMutable[x][y] == -1 {
isWaterMutable[x][y] = currentHeight
queue.append((x, y))
}
}
}
}
currentHeight += 1
}
return isWaterMutable
}
}
Я использую BFS (поиск в ширину), который реализуется с помощью структуры данных Queue. При реализации я активно пользовался Google, т.к. для меня оказалось трудностью элементарное использование
for
цикла. Но это оказалось вполне посильным. Некоторые интересные моменты, которые я подметил для себя:
tuple
: выражение вида (i, j) и let x = i + direction.0
. Это простой способ работы с парами значений, который позволяет делать код более читаемым и удобным.if
: В отличие от Kotlin, в Swift скобки не обязательны для одиночных операторов внутри if. В Kotlin я привык писать if (condition) { ... }
, но в Swift можно написать if condition и это будет работать.range
: В Swift для работы с диапазонами используется синтаксис 0..<n
или 0...n-1
, в то время как в Kotlin аналогичный диапазон записывается как 0 until n
или 0..n-1
.let
: В Swift let защищает коллекции от модификации, что оказалось довольно удобным и безопасным. Это добавляет уверенности, что коллекции не будут случайно изменены. Любопытно как это реализовано Маленькая задача, а сколько открытий! Предвкушаю, что меня ждёт дальше в изучении Swift
#leetcode
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1👀1
Мой прогресс в изучении Swift 🔢
Я продвигаюсь быстрее, чем успеваю делиться здесь своими успехами. Исправляю это недоразумение… но поэтапно, чтобы всё было удобно воспринимать:
➡️ Day 4: Type annotations and checkpoint 2
Этот урок не открыл для меня ничего принципиально нового — большинство концепций уже знакомо мне из Kotlin.
💡 Однако узнал пару интересных моментов:
🟢 Array в Swift — это аналог List в Kotlin.
🟢 У Array нет встроенного метода для удаления дубликатов. Для этого нужно преобразовать его в Set (который автоматически удаляет дубликаты) и при необходимости снова в Array.
➡️ Day 5: If, switch, and the ternary operator
В этом уроке мне не понравилась структура подачи материала: автор начинает с демонстрации различных видов сравнений, а только потом объясняет, что всё это базируется на boolean, и общий вид конструкции следующий:
На мой взгляд, понять логику проще, если сначала объяснить общий вид, а потом привести пару примеров.
💡 Интересное из урока:
🟢 В 🙊 Если у кого-то есть идеи или примеры, буду рад услышать!
#hackingwithswift
Я продвигаюсь быстрее, чем успеваю делиться здесь своими успехами. Исправляю это недоразумение… но поэтапно, чтобы всё было удобно воспринимать:
Этот урок не открыл для меня ничего принципиально нового — большинство концепций уже знакомо мне из Kotlin.
В этом уроке мне не понравилась структура подачи материала: автор начинает с демонстрации различных видов сравнений, а только потом объясняет, что всё это базируется на boolean, и общий вид конструкции следующий:
if (boolean) {
// some code
} else {
// some code
}
На мой взгляд, понять логику проще, если сначала объяснить общий вид, а потом привести пару примеров.
switch
есть возможность “проваливаться” в следующий case без проверки его условия, используя ключевое слово fallthrough
. Однако пока я не совсем понял, в каких случаях это реально полезно. #hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👏1🤔1
Едем дальше 🚗 :
➡️ Day 6: Loops, summary, and checkpoint 3
Циклы это один из основных строительных блоков. Swift блестяще справляется с реализацией этой абстракции.
Единственное отличие, которое я нашёл, это отсутствие labels (метки) как
Но этот функционал я нахожу немного спорным, как и
#hackingwithswift
Циклы это один из основных строительных блоков. Swift блестяще справляется с реализацией этой абстракции.
Единственное отличие, которое я нашёл, это отсутствие labels (метки) как
outer@
в следующем примере
outer@ for (i in 1..3) {
for (j in 1..3) {
if (j == 2) break@outer
println("i: $i, j: $j")
}
}
Но этот функционал я нахожу немного спорным, как и
break
& continue
, т.к. это усложняет читабельность кода.#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👨💻1
Интересный топик, т.к. тут я нашёл для себя отличный функционал, а именно алиасы (ака внешнее имя) для параметров. Выглядит это так:
func printTimesTables(for number: Int) {
for i in 1...12 {
print("\(i) x \(number) is \(i * number)")
}
}
printTimesTables(for: 5)
Внутри функции мы обращаемся к параметру как
number
, а при вызове - используем более понятное имя for
. Это значительно улучшает читаемость и восприятие кода.Кстати, Swift позволяет использовать даже зарезервированные слова вроде
for
в качестве алиасов, что тоже приятно удивляет.А вот работа с Tuple оказалась приятной неожиданностью.
func printTupleValues(tuple: (a: Int, b: Int, c: Int)) {
print(tuple.a)
print(tuple.b)
print(tuple.c)
}
printTupleValues(tuple: (1, 2, 3))
printTupleValues(tuple: (a: 2, b: 3, c: 1))
В Kotlin отсутствует встроенная структура данных, аналогичная кортежам в Swift. Вместо этого там есть
Pair
(для двух элементов) и Triple
(для трёх элементов). Если требуется больше элементов, обычно используются data class или списки.Однако возможность именовать параметры внутри кортежей в Swift выглядит как интересное и удобное решение. Пока что я не уверен, насколько это полезно на практике, но выглядит элегантно.
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
В ближайшие дни я планирую закончить с первыми 14 уроками, которые посвящены основам Swift как языка. Эти уроки дают базу, необходимую для понимания ключевых концепций, таких как работа с типами, функциями и структурами данных. Всё это несомненно пригодится в дальнейшем.
Что дальше?
После этого нас ждет работа с серией занятий про SwiftUI - жду с нетерпением!🥺
Что дальше?
После этого нас ждет работа с серией занятий про SwiftUI - жду с нетерпением!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2⚡1🎉1
Дефолтные значения параметров не стали для меня откровением, так как они присутствуют и в Kotlin, поэтому тут всё ожидаемо.
А вот конструкция для перехвата исключений выглядит немного странно
do {
try throwingFunction1()
nonThrowingFunction1()
try throwingFunction2()
nonThrowingFunction2()
try throwingFunction3()
} catch {
// handle errors
}
Думаю, когда я буду писать подобные конструкции, понимание такого решения будет более понятным.
Пока мне всё же привычно как это выглядит в Kotlin:
try {
// Code that may throw an exception
} catch (e: SomeException) {
// Code for handling the exception
}
В остальном тема исключений довольно таки общая для многих языков программирования.
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Большая тема впереди
➡️ Day 9: Closures, passing functions into functions, and checkpoint 5
В переменной можно хранить функцию:
📌 Запишу в #todo list: “изучить как это работает внутри”
Получается мы можем использовать функцию как аргумент для другой функции - это функции первого класса (first-class functions), в современных языках вполне распространённая штука!
Понравилось как авторы Swift задизайнили неявное именование аргументов
В Kotlin доступен только один неявный параметр, который называется
Эта тема очень важная, т.к. эти знания пригодятся почти в любом проекте👩💻
#hackingwithswift
В переменной можно хранить функцию:
func greetUser() {
print("Hi there!")
}
greetUser()
var greetCopy = greetUser
greetCopy()
Получается мы можем использовать функцию как аргумент для другой функции - это функции первого класса (first-class functions), в современных языках вполне распространённая штука!
Понравилось как авторы Swift задизайнили неявное именование аргументов
let reverseTeam = team.sorted { $0 > $1 }
В Kotlin доступен только один неявный параметр, который называется
it
. Если понадобится использовать 2 и больше параметра - нужно будет явно написать названия этих параметров.Эта тема очень важная, т.к. эти знания пригодятся почти в любом проекте
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
Под недавними постами вы можете оставить комментарий ✏️
Буду рад вашему фидбэку!
Также поддержите меня реакциями — это даст дополнительную мотивацию делиться своим прогрессом в деталях🙏
Буду рад вашему фидбэку!
Также поддержите меня реакциями — это даст дополнительную мотивацию делиться своим прогрессом в деталях
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1👀1
Если кто-то проходит этот же курс, или будете рекомендовать его друзьям, не забудьте выделить важность Optional статей, они не содержат видео и небольшие по объему. Несмотря на то, что они подаются как оциональные - материал действительно стоящий внимания.
Отдельно подчеркну, что наличие текста под каждым видео невероятно полезно! Это позволяет воспользоваться поиском, скопировать листинги показанные на видео, или же воспользоваться переводчиком и лучше понять, то о чем рассказывает автор.
#hackingwithswift
Отдельно подчеркну, что наличие текста под каждым видео невероятно полезно! Это позволяет воспользоваться поиском, скопировать листинги показанные на видео, или же воспользоваться переводчиком и лучше понять, то о чем рассказывает автор.
#hackingwithswift
👍2
Это очень круто! Пока мне не понятно в чём существенное отличие
struct
& class
(об этом будет потом). Но подход к mutable/immutable объектам (если они называются объектами, наверное, точнее будет определение экземпляр структуры) домонстрирует совершенно новый для меня подход.В примере автора демонстрируется
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
var vacationRemaining: Int {
get {
vacationAllocated - vacationTaken
}
set {
vacationAllocated = vacationTaken + newValue
}
}
init
это аналог constructor
в Kotlin. Позволяет задать явный конструктор с различным набором параметров.С
self
тоже всё довольно таки просто - это аналог this
в Java & Kotlin. Если название поля совпадает с именем параметра, то self
позволит их отличить.
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
Изначально я ожидал, что это будет большая тема, но зная что такое
В целом классы в Swift очень похожи на классические классы ООП. Тут есть практически всё, что есть в
Несмотря на то, что обе переменные объявлены с помощью
В случае использования
Также есть тонкости с тем, когда Swift удаляет ненужные объекты. Но это отдельный топик требующий внимания #todo
#hackingwithswift
Модификаторы доступа всегда вызывают у меня смешанные чувства. Я отношусь к ним скептически. Пока у меня складывается ощущение, что мне не придётся писать сложную иерархию классов, а поэтому я буду ограничен только использованием этих модификаторов в библиотечных классах.
Статические поля и методы, они и в Африке статические
Изначально я ожидал, что это будет большая тема, но зная что такое
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. И
Насколько я понял, это тип будущей реализации протокола (как в случае с Self) или же какой-то тип, который будет определён в реализации протокола (как в случае с associatedtype). Выглядит как продвинутые фишки, но полезны они, скорее всего, авторам библиотек. #todo хочется изучить этот концепт более детально!
К слову, в Kotlin это достигается с помощью шаблонов (generics), но возможно есть ключевые отличия. И я жду, когда же в Swift я увижу🤔
🤣
Extensions
Так же присутствуют в Kotlin. Возможность добавить новый функционал для уже существующих
Кстати, это и механизм для создания дефолтной реализации метода в протоколе. В Java/Kotlin это можно сделать напрямую в определении интерфейса.
Хоть меня сложно испугать типами, после того как я осилил Higher-Kinded Types в Scala👩💻 , Self, associatedtype, type erasure, some, any заставляют извилины пошевелиться вновь 🧠
#hackingwithswift
Протоколы это что-то вроде интерфейсов в 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
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Концепция опциональных (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-сниппеты - но мне не нравится, как это выглядит с большим количеством кода.
🟢 Прикреплять код как изображения - возможно, так будет проще для восприятия, но зумить и искать по ним не получится
Если у кого-то есть идеи по этому вопросу - буду рад, если вы поделитесь!😇
Дальше, скорее всего, будет много кода, и меня немного смущает, как Telegram отображает сниппеты. Например, нет нумерации строк, что не очень удобно.
Поэтому я думаю, как лучше оформить код в постах. Основное внимание будет на скриншотах приложений, но я также хочу делиться самим кодом.
Вот какие варианты я рассматриваю:
Если у кого-то есть идеи по этому вопросу - буду рад, если вы поделитесь!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🤔1
Какой формат подходит больше всего?
Anonymous Poll
80%
Не хочу переходить на внешние ресурсы (как GitHub)
20%
Готов читать листинги на внешних ресурсах
0%
Вообще не хочу их читать, дай мне скриншот
Нууу.. начинаем 🔢 👶
Первым проектом будет приложения для разделения счёта в кафе/ресторане
Проект состоит из 3х частей, попробую осилить за один день
https://www.hackingwithswift.com/100/swiftui/16
#hackingwithswift
Первым проектом будет приложения для разделения счёта в кафе/ресторане
Проект состоит из 3х частей, попробую осилить за один день
https://www.hackingwithswift.com/100/swiftui/16
#hackingwithswift
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1👏1