Swift встречает искусственный интеллект: почему это важно прямо сейчас
Представьте: вы пишете приложение для iOS, и вдруг ваш пользователь может просто спросить у него: «Как приготовить пасту карбонара?» — и получить не ссылку на Википедию, а живой, развёрнутый ответ. Или попросить: «Напиши письмо начальнику о переносе дедлайна» — и через секунду черновик готов. Звучит как магия? Нет, это Swift + ChatGPT.
В 2024 году интеграция языковых моделей в мобильные приложения перестала быть уделом гигантов. Теперь любой разработчик на Swift может добавить искусственный интеллект в своё приложение за вечер. И сегодня я покажу вам, как это сделать — с реальным кодом, без воды и с пониманием того, что происходит под капотом.
Кстати, если вы только начинаете свой путь в Swift и хотите глубже разобраться с основами, PythonLib — отличное место, чтобы подтянуть базу перед тем, как нырять в AI. А теперь — к делу.
Шаг 1. Готовим окружение: что нужно для работы с ChatGPT в Swift
Прежде чем писать код, давайте убедимся, что у вас есть всё необходимое. Вам понадобится:
- Xcode 15.0 или новее (желательно — последняя версия)
- iOS 16.0+ (чтобы использовать
async/awaitбез костылей) - API-ключ от OpenAI (регистрируетесь на platform.openai.com, создаёте ключ)
- Библиотека для работы с сетью — мы будем использовать
URLSession, так что никаких сторонних зависимостей не нужно
Важный совет: никогда не храните API-ключ прямо в коде. Используйте .xcconfig файлы или серверный прокси. В примерах я покажу, как читать ключ из Info.plist, но в продакшене обязательно шифруйте или используйте бэкенд.
Шаг 2. Создаём структуру запроса к ChatGPT
ChatGPT использует API OpenAI, который принимает JSON и возвращает ответ модели. Давайте создадим простую, но рабочую структуру для отправки сообщений.
Модели данных
// Модель сообщения
struct Message: Codable {
let role: String // "system", "user" или "assistant"
let content: String
}
// Модель запроса
struct ChatGPTRequest: Codable {
let model: String
let messages: [Message]
let temperature: Double?
}
// Модель ответа
struct ChatGPTResponse: Codable {
struct Choice: Codable {
let message: Message
}
let choices: [Choice]
}
Обратите внимание на temperature — это параметр креативности. Значение 0.0 делает ответы строгими и фактологичными, 1.0 — творческими. Для чат-бота ставьте 0.7, для генерации идей — 0.9.
Сервис для работы с API
class ChatGPTService {
private let apiKey: String
private let baseURL = "https://api.openai.com/v1/chat/completions"
init() {
// Читаем ключ из Info.plist (только для тестов!)
guard let key = Bundle.main.object(forInfoDictionaryKey: "OPENAI_API_KEY") as? String else {
fatalError("API Key not found")
}
self.apiKey = key
}
func sendMessage(_ text: String) async throws -> String {
let messages = [
Message(role: "system", content: "Ты — полезный ассистент iOS-разработчика. Отвечай кратко, на русском языке."),
Message(role: "user", content: text)
]
let requestBody = ChatGPTRequest(
model: "gpt-3.5-turbo",
messages: messages,
temperature: 0.7
)
var request = URLRequest(url: URL(string: baseURL)!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.httpBody = try JSONEncoder().encode(requestBody)
let (data, _) = try await URLSession.shared.data(for: request)
let response = try JSONDecoder().decode(ChatGPTResponse.self, from: data)
return response.choices.first?.message.content ?? "Нет ответа"
}
}
Этот сервис — база. Он асинхронный, использует современный async/await и обрабатывает базовые ошибки. Но в реальном проекте вам понадобится обработка ошибок, ретраи и логирование. Не забывайте про лимиты токенов!
Шаг 3. Интеграция в SwiftUI: делаем красивый интерфейс
Теперь давайте прикрутим наш AI-сервис к пользовательскому интерфейсу. Создадим простой чат SwiftUI с историей сообщений.
struct ChatView: View {
@State private var messages: [Message] = []
@State private var inputText: String = ""
@State private var isLoading = false
private let chatService = ChatGPTService()
var body: some View {
VStack {
ScrollView {
ForEach(messages, id: \.content) { message in
HStack {
if message.role == "user" {
Spacer()
Text(message.content)
.padding()
.background(Color.blue.opacity(0.2))
.cornerRadius(12)
} else {
Text(message.content)
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(12)
Spacer()
}
}
.padding(.horizontal)
}
if isLoading {
ProgressView()
.padding()
}
}
HStack {
TextField("Напишите сообщение...", text: $inputText)
.textFieldStyle(RoundedBorderTextFieldStyle())
.disabled(isLoading)
Button(action: sendMessage) {
Image(systemName: "paperplane.fill")
}
.disabled(inputText.isEmpty || isLoading)
}
.padding()
}
}
private func sendMessage() {
guard !inputText.isEmpty else { return }
let userMessage = Message(role: "user", content: inputText)
messages.append(userMessage)
isLoading = true
Task {
do {
let reply = try await chatService.sendMessage(inputText)
let assistantMessage = Message(role: "assistant", content: reply)
messages.append(assistantMessage)
} catch {
let errorMessage = Message(role: "assistant", content: "Ошибка: \(error.localizedDescription)")
messages.append(errorMessage)
}
isLoading = false
inputText = ""
}
}
}
Вот так, меньше 100 строк кода — и у вас свой AI-ассистент в приложении. Выглядит стильно, работает быстро, а главное — пользователи будут в восторге.
Шаг 4. Продвинутые техники: контекст и системные промпты
Одна из главных фишек ChatGPT — это контекст. Вы можете передавать всю историю диалога, и модель будет помнить, о чём говорили раньше. Давайте улучшим наш сервис:
func sendMessageWithContext(_ text: String, history: [Message]) async throws -> String {
let systemMessage = Message(
role: "system",
content: "Ты — эксперт по Swift и iOS разработке. Отвечай с примерами кода, если это уместно."
)
var allMessages = [systemMessage] + history
allMessages.append(Message(role: "user", content: text))
// Считаем примерное количество токенов (4 символа ≈