Modern Swift ortamları için async/await tabanlı, test edilebilir ve genişletilebilir sözlük/kelime verisi istemcisi.
- Özet
- Mimari ve Tasarım Kararları
- Gereksinimler
- Kurulum (Swift Package Manager)
- Hızlı Başlangıç
- API Referansı
- Test Çalıştırma
- DocC Dokümantasyonu
- Sürümleme ve Yol Haritası
- Katkı Rehberi
- Lisans
WordKit, sözlük servislerinden kelime girişlerini almak için yalın bir istemci sunar. Odak noktaları:
- Async/Await destekli modern API yüzeyi
- Bağımlılıksız ve hafif
- Test edilebilir mimari (enjekte edilebilir
URLSession, mock’lar) - Anlamlı hata modeli ve tip-güvenli dönüşler
Not: Depo MIT lisanslıdır. Ayrıntı için
LICENSEdosyasına bakın.
- Katmanlı yapı:
WordAPI(public yüz) →APIClient(istek/yanıt ayrıştırma) → Modeller (WordEntry,Meaning,Definition,Phonetic,APIError). - Bağımlılık enjeksiyonu:
Testlerde özelleştirilmişURLSession(ör.MockURLProtocol) ile deterministik ağ senaryoları. - Sağlam hata ayrımı:
2xx başarı, 404 için alan-özel hata (wordNotFound), diğer durumlar için genel istek hatası.
- Swift: 5.9+ (önerilir)
- Xcode: 15+
- Platformlar (öneri): iOS 13+, macOS 11+, tvOS 14+, watchOS 8+
Minimum sürümler projeye göre gevşetilebilir/sıkılaştırılabilir.
- File → Add Packages...
- URL alanına:
https://github.com/CanSagnak1/WordKit.git - Uygun branch/tag seçin ve ekleyin.
// swift-tools-version:5.9
import PackageDescription
let package = Package(
name: "YourApp",
platforms: [
.iOS(.v13), .macOS(.v11), .tvOS(.v14), .watchOS(.v8)
],
dependencies: [
.package(url: "https://github.com/CanSagnak1/WordKit.git", from: "0.1.0")
],
targets: [
.target(
name: "YourApp",
dependencies: [
.product(name: "WordAPI", package: "WordKit")
]
)
]
)import WordAPI
let api = WordAPI() // varsayılan yapılandırma
Task {
do {
let entries = try await api.fetch(word: "serendipity", language: .en)
// entries: [WordEntry]
if let first = entries.first {
print("Word:", first.word)
print("Meanings:", first.meanings.map(\.partOfSpeech))
}
} catch {
// Aşağıdaki Hata Modeli bölümüne bakın
print("Fetch failed:", error)
}
}WordAPI, kelime girişlerini getirmek için ana geçittir.
public final class WordAPI {
/// Varsayılan `URLSessionConfiguration` ve endpoint ile kurulum.
public init(configuration: URLSessionConfiguration = .default,
baseURL: URL? = nil)
/// Belirtilen dilde bir kelime için sözlük girdilerini döndürür.
public func fetch(word: String,
language: Language,
timeout: TimeInterval? = nil) async throws -> [WordEntry]
}Özellikler
baseURLözelleştirilebilir (test/alternatif endpoint’ler için).timeouthemURLRequestseviyesinde hem deTasktabanlı olarak uygulanabilir.- Varsayılan
Accept: application/jsonbaşlığı set edilir.
public struct WordEntry: Codable, Identifiable {
public let id: String // deterministik kimlik
public let word: String
public let phonetics: [Phonetic]
public let meanings: [Meaning]
}
public struct Phonetic: Codable, Identifiable {
public let text: String?
public let audio: String?
public let sourceUrl: String?
public var id: String { ... } // içerik-tabanlı kimlik
}
public struct Meaning: Codable, Identifiable {
public let partOfSpeech: String
public let definitions: [Definition]
public var id: String { ... } // içerik-tabanlı kimlik
}
public struct Definition: Codable, Identifiable {
public let definition: String
public let example: String?
public let synonyms: [String]?
public let antonyms: [String]?
public var id: String { ... }
}
public struct APIError: Codable, Equatable {
public let title: String
public let message: String
public let resolution: String?
}Identifiable Notu: UUID üretmek yerine içerik-tabanlı deterministik ID’ler kullanılır; bu sayede diffable veri kaynaklarında kararlılık sağlanır.
public enum NetworkError: Error, Equatable {
case invalidURL
case networkError(underlying: Error)
case requestFailed(statusCode: Int, body: Data?)
case decodingError(underlying: Error)
case wordNotFound(APIError)
}Yakalama Örneği
do {
let entries = try await api.fetch(word: "kitten", language: .en)
} catch let error as NetworkError {
switch error {
case .wordNotFound(let apiError):
print("Not found:", apiError.message)
case .requestFailed(let code, _):
print("HTTP \(code)")
default:
print("General error:", error)
}
} catch {
print("Unexpected:", error)
}public enum Language: String, Codable, CaseIterable {
case en, tr, es, de, fr, it, ptBR, ru, ja, ko, zh
// Servis desteğine göre güncellenebilir.
}İpucu: Üçüncü taraf API’lerin kabul ettiği dil kodları servis dokümantasyonuna göre birebir eşlenmelidir.
Languageenum’unu servis matrisine göre genişletin veyaunknown(rawValue:)stratejisi kullanın.
var config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 15
let api = WordAPI(configuration: config,
baseURL: URL(string: "https://api.dictionaryapi.dev/api/v2/entries")!)Gelişmiş Ayarlar
- Başlıklar:
User-Agent,Accept-Languageeklemek isteyebilirsiniz. - Retry politikası: 5xx durumları için basit üssel geri çekilmeli (exponential backoff) bir strateji eklenebilir.
- İptal Edilebilirlik:
Task’i saklayarak iptal (task.cancel()) uygulanabilir.
Projede birim testler XCTest ile yazılmıştır (mock URL protokolü ve fixture’lar).
swift test
# veya Xcode üzerinden Product > TestÖnerilen Ek Testler
- Zaman aşımı ve iptal senaryoları
- 5xx durumlarında retry
- Dil varyantları (
pt-BRgibi) için doğru URL oluşumu - Başlıklar (
Accept,User-Agent) set edildi mi?
DocC üretimi için:
xcodebuild docbuild \
-scheme WordAPI \
-destination 'generic/platform=iOS'Ardından .doccarchive’ı Xcode Organizer üzerinden veya statik web dağıtımıyla yayınlayabilirsiniz.
SemVer takip edilir: MAJOR.MINOR.PATCH
Planlananlar
- 5xx retry ve özelleştirilebilir
RetryPolicy - Yerleşik basit önbellek katmanı
- Gelişmiş
Languagematrisi ve doğrulama - Örnek iOS demo uygulaması
- DocC içinde rehber (How-to) makaleleri
Katkılar memnuniyetle karşılanır:
- Issue açın (hata/öneri).
- Fork → feature branch → PR.
- PR’larda test eklemeyi ve SwiftLint/format kontrolünü (varsa) geçmeyi unutmayın.
Bu proje MIT lisanslıdır. Ayrıntılar için LICENSE dosyasına bakın.