Введение
Разработка под iOS — это постоянное решение однотипных задач: от настройки таблиц до управления состоянием. Промты (prompts) для AI-ассистентов, таких как ChatGPT или GitHub Copilot, позволяют автоматизировать рутину и сосредоточиться на бизнес-логике. В этой подборке — 12 проверенных промтов для SwiftUI, UIKit, Core Data и Combine, которые я использую в реальных проектах. Каждый промт сопровождается примером кода и объяснением, почему он работает. Источник вдохновения — официальные гайды Apple (SwiftUI Essentials, Core Data Programming Guide) и опыт коммерческой разработки.
Базовые промты для SwiftUI
1. SwiftUI: Кастомный список с swipe-действиями
Задача — добавить к элементам списка кнопки «Удалить» и «Избранное». Промт: «Напиши SwiftUI-компонент, который отображает массив строк в виде списка с возможностью свайпа для удаления и добавления в избранное. Используй List, ForEach и .swipeActions.»
Результат:
struct SwipeableListView: View {
@State private var items = ["Item1", "Item2", "Item3"]
@State private var favorites: Set<String> = []
var body: some View {
List {
ForEach(items, id: \.self) { item in
Text(item)
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
items.removeAll { $0 == item }
} label: {
Label("Delete", systemImage: "trash")
}
Button {
favorites.insert(item)
} label: {
Label("Favorite", systemImage: "star")
}
.tint(.yellow)
}
}
}
}
}
2. SwiftUI: Анимированная смена темы
Задача — плавно переключать между светлой и тёмной темой. Промт: «Реализуй EnvironmentObject для хранения текущей темы (light/dark) и анимируй смену с помощью withAnimation.»
Результат:
class ThemeManager: ObservableObject {
@Published var isDarkMode = false
}
struct ContentView: View {
@EnvironmentObject var theme: ThemeManager
var body: some View {
VStack {
Toggle("Dark Mode", isOn: $theme.isDarkMode)
.padding()
.animation(.easeInOut(duration: 0.4), value: theme.isDarkMode)
}
.preferredColorScheme(theme.isDarkMode ? .dark : .light)
}
}
3. UIKit: UITableView с динамической высотой ячейки
Задача — таблица, в которой ячейки растягиваются под контент. Промт: «Настрой UITableView так, чтобы высота ячейки вычислялась автоматически на основе содержимого UILabel с несколькими строками. Используй estimatedRowHeight и automaticDimension.»
Результат:
class DynamicTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 44
tableView.rowHeight = UITableView.automaticDimension
}
// ... dataSource с разными длинами текста
}
4. UIKit: Кастомный аниматор перехода
Задача — создать переход между контроллерами с масштабированием. Промт: «Реализуй UIViewControllerAnimatedTransitioning для push-анимации, при которой новый контроллер выезжает снизу с пружинкой.»
Результат:
class ScaleAnimator: NSObject, UIViewControllerAnimatedTransitioning {
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let toView = transitionContext.view(forKey: .to) else { return }
toView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
transitionContext.containerView.addSubview(toView)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.8) {
toView.transform = .identity
} completion: { finished in
transitionContext.completeTransition(finished)
}
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 0.5 }
}
Продвинутые промты для Core Data
5. Core Data: Сохранение с обработкой ошибок
Задача — сохранить объект в Core Data и корректно обработать ошибки. Промт: «Напиши функцию, которая создаёт новый объект UserEntity и сохраняет контекст. В случае ошибки покажи alert в SwiftUI.»
Результат:
func saveUser(name: String, age: Int16) {
let context = PersistenceController.shared.container.viewContext
let newUser = UserEntity(context: context)
newUser.name = name
newUser.age = age
do {
try context.save()
} catch {
print("Failed to save: \(error.localizedDescription)")
// Показ alert через @State
}
}
6. Core Data: FetchRequest с фильтрацией и сортировкой
Задача — запрос пользователей старше 18, отсортированных по имени. Промт: «Создай NSFetchRequest с предикатом и сортировкой, оберни его в @FetchRequest для SwiftUI.»
Результат:
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \UserEntity.name, ascending: true)],
predicate: NSPredicate(format: "age >= 18")
) var adultUsers: FetchedResults<UserEntity>
7. Combine: Связывание TextField и метки
Задача — обновлять текст метки при каждом вводе в TextField. Промт: «Используй @Published и sink из Combine для реактивного обновления.»
Результат:
class ViewModel: ObservableObject {
@Published var input: String = ""
@Published var output: String = ""
private var cancellables = Set<AnyCancellable>()
init() {
$input
.map { $0.uppercased() }
.sink { [weak self] value in
self?.output = value
}
.store(in: &cancellables)
}
}
8. Combine: Debounce для поиска
Задача — отправлять запрос на сервер только после паузы в вводе. Промт: «Добавь debounce(for: 0.5) на поисковый запрос.»
Результат:
searchQueryPublisher
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.removeDuplicates()
.sink { query in
// Вызов API
}
.store(in: &cancellables)
9. SwiftUI: UIViewRepresentable для карты
Задача — встроить MKMapView в SwiftUI. Промт: «Реализуй UIViewRepresentable для отображения карты с кастомными аннотациями.»
Результат:
struct MapView: UIViewRepresentable {
@Binding var region: MKCoordinateRegion
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
uiView.setRegion(region, animated: true)
}
// Coordinator и методы делегата
}
10. Unit-тесты: Тестирование модели Core Data
Задача — написать тест для сохранения и извлечения данных. Промт: «Используй XCTest и in-memory container для изолированного теста.»
Результат:
func testSaveUser() {
let container = PersistenceController(inMemory: true).container
let context = container.viewContext
let user = UserEntity(context: context)
user.name = "Test"
try? context.save()
let request = NSFetchRequest<UserEntity>(entityName: "UserEntity")
let result = try? context.fetch(request)
XCTAssertEqual(result?.first?.name, "Test")
}
11. Локализация в SwiftUI через LocalizedStringKey
Задача — перевод интерфейса на несколько языков. Промт: «Используй LocalizedStringKey и строковые ключи в String Catalog.»
Результат:
Text(LocalizedStringKey("welcome_message"))
.padding()
12. Оптимизация производительности списков
Задача — убрать лишние перерисовки в длинном списке. Промт: «Добавь Identifiable протокол и lazy стеки.»
Результат:
struct Item: Identifiable {
let id = UUID()
let text: String
}
LazyVStack {
ForEach(items) { item in
Text(item.text)
}
}
Заключение
Эти 12 промтов покрывают 80% ежедневных задач iOS-разработчика. Используйте их как шаблоны — адаптируйте под свои проекты и комбинируйте. Для углублённого изучения рекомендую официальные источники Apple и наши статьи на asibiont.com/blog. Освоив промты, вы сократите время на рутину и сможете больше экспериментировать с архитектурой.
Комментарии