“Calismiyor.”
Bir iOS uygulamasinin destegini yaptiysan, bu sinir bozucu derecede belirsiz kullanici geri bildirimini almissindir. Yeniden olusturma adimlari yok, hata mesaji yok, baglam yok – sadece seni cevaptan cok soruyla basi basa birakan o korkunc “calismiyor” raporu.
En detayci kullanicilar bile sorunlari teshis etmek icin hangi bilgiye ihtiyacin oldugunu nadiren bilir. Yardim etmeye calistiklarinda bile, dogru detaylari saglayacak teknik bilgiye sahip olmayabilirler. Bu kopukluk herkes icin sinir bozucu bir deneyim yaratiyor.
Bu yazida, bu bosluyu kapatmak icin ErrorKit icerisinde uyguladigim iki pratik yaklasimi paylasacagim: otomatik olarak tanisal loglar toplayan basit bir geri bildirim butonu ve dogrudan kullanici raporlari olmadan bile kaliplari belirlemenize yardimci olan yapilandirilmis bir hata analitigi yaklasimi.
Eksik Baglam Sorunu
Kullanicilar sorunlarla karsilastiginda, teshisi zorlastiran birkac engel var:
Hangi bilgiye ihtiyacin oldugunu bilmiyorlar
Sistem loglarina kolayca eriselemiyorlar
Tam adimlari hatirlayip ifade etmekte zorlaniyorlar
Karmasik sorunlar birden fazla bileseni icerebilir
Aralikli sorunlari talep uzerine yeniden uretmek zor
Duzgun bir baglam olmadan hata ayiklama bir tahmin oyununa donusuyor. Dogru bilgiyle dakikalar icinde cozulebilecek bir sorunu yeniden uretmeye calisarak saatler harcayabilirsin.
Cozum 1: Log Ekli Geri Bildirim Butonu
Ilk cozum, kullanicilarin sana eksiksiz bilgi gondermesini son derece kolaylastirmak. ErrorKit, otomatik log toplama ile bir mail olusucu ekleyen bir SwiftUI modifier’i sunuyor:
struct ContentView: View {
@State private var showMailComposer = false
var body: some View {
VStack {
// Your app content
Button("Report a Problem") {
showMailComposer = true
}
.mailComposer(
isPresented: $showMailComposer,
recipient: "[email protected]",
subject: "YourApp Bug Report",
messageBody: """
Please describe what happened:
----------------------------------
Device: \(UIDevice.current.model)
iOS: \(UIDevice.current.systemVersion)
App version: \(Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown")
""",
attachments: [
try? ErrorKit.logAttachment(ofLast: .minutes(30))
]
)
}
}
}Bu basit bir “Sorun Bildir” butonu olusturuyor ve su isleri yapiyor:
Onceden doldurulmus bir e-posta olusucu aciyor
Cihaz ve uygulama bilgilerini iceriyor
Otomatik olarak yakin zamandaki sistem loglarini ekliyor
Kullanicinin sorunu aciklamasi icin alan sagliyor
Buradaki gizli sos log eki. Kullanici bir sorunla karsilastiktan sonra bu butona dokunursa, sorun olustugunda uygulamanda ve cevresinde neler olduguna dair kapsamli bir tablo elde ediyorsun.
Apple’in Unified Logging Sisteminden Yararlanmak
ErrorKit, tanisal bilgi toplamak icin Apple’in unified logging sistemi (OSLog/Logger) kullaniyor. Henuz yapilandirilmis loglama kullanmiyorsan, iste kisa bir giris:
import OSLog
// Create loggers
let logger = Logger()
// or with subsystem and category
let networkLogger = Logger(subsystem: "com.yourapp", category: "networking")
// Log at appropriate levels
logger.debug("Detailed connection info") // Development debugging
logger.info("User tapped submit button") // General information
logger.notice("Profile successfully loaded") // Important events
logger.error("Failed to load user data") // Errors that should be fixed
logger.fault("Database corruption detected") // System failures
// Format values and control privacy
logger.info("User \(userId, privacy: .private) logged in from \(ipAddress, privacy: .public)")Unified logging sistemi print() ifadelerine kiyasla birkac avantaj sagliyor:
Bilgi filtreleme icin log seviyeleri
Hassas veriler icin gizlilik kontrolleri
Minimal ek yukle verimli performans
Uygulama yeniden baslatmalari arasinda kalicilik
Kapsamli Log Toplama
ErrorKit’in yaklasiminin onemli bir avantaji, sadece uygulamanin loglarini degil, ayni zamanda sunlardan gelen ilgili loglari da yakalamasi:
Apple’in unified logging sistemini kullanan ucuncu parti framework’ler
Uygulamanin etkilestigi sistem bilesenleri (ag, dosya sistemi vb.)
Uygulamanin islevselligiyle ilgili arka plan surecleri
Bu, sorun olustugunda uygulamanda ve cevresinde neler olduguna dair tam bir tablo sunuyor – sadece kendin acikca ekledigin loglar degil.
Log Toplamayi Kontrol Etmek
Detay ve gizlilik arasinda denge kurmak icin log toplamayi ozellestirebilirsin:
// Collect logs from last 30 minutes with notice level or higher (default)
try ErrorKit.logAttachment(ofLast: .minutes(30), minLevel: .notice)
// Collect logs from last hour with error level or higher (less verbose)
try ErrorKit.logAttachment(ofLast: .hours(1), minLevel: .error)
// Collect logs from last 5 minutes with debug level (very detailed)
try ErrorKit.logAttachment(ofLast: .minutes(5), minLevel: .debug)minLevel parametresi loglari oneme gore filtreliyor:
.debug: Tum loglar (cok detayli).info: Bilgilendirme loglari ve ustundekiler.notice: Dikkat cekici olaylar (varsayilan).error: Sadece hatalar ve arizalar.fault: Sadece kritik hatalar
Bu, teshis icin ihtiyacin olan baglami saglarken ne kadar bilgi toplayacagin uzerinde kontrol sagliyor.
Daha Fazla Kontrol Icin Alternatif Yontemler
Log isleme uzerinde daha fazla kontrole ihtiyacin varsa, ErrorKit ek yaklasimlar sunuyor:
Log Verisini Dogrudan Alma
Kendi backend’ine log gondermek veya uygulama icinde islemek icin loggedData kullan:
let logData = try ErrorKit.loggedData(
ofLast: .minutes(10),
minLevel: .notice
)
// Use the data with your custom reporting system
analyticsService.sendLogs(data: logData)Gecici Dosyaya Aktarma
Loglari baska mekanizmalarla paylasmak icin exportLogFile kullan:
let logFileURL = try ErrorKit.exportLogFile(
ofLast: .hours(1),
minLevel: .error
)
// Share the log file
let activityVC = UIActivityViewController(
activityItems: [logFileURL],
applicationActivities: nil
)
present(activityVC, animated: true)Cozum 2: Gruplama ID’leriyle Akilli Hata Analitigi
Geri bildirim butonu kullanicilarin fark ettigi sorunlari bildirmelerine yardimci olurken, bircok sorun bildirilmeden kaliyor. Kullanicilar bir hatayla karsilasabilir, omuz silkip tekrar deneyebilir ve sana hic bahsetmeyebilir. Iste burada hata analitigi devreye giriyor.
ErrorKit, hatalari otomatik olarak izlemek ve akilli bir sekilde gruplamak icin araclar sagliyor:
func handleError(_ error: Error) {
// Get a stable ID that ignores dynamic parameters
let groupID = ErrorKit.groupingID(for: error)
// Get the full error chain description
let errorDetails = ErrorKit.errorChainDescription(for: error)
// Send to your analytics system
Analytics.track(
event: "error_occurred",
properties: [
"error_group": groupID,
"error_details": errorDetails,
"user_id": currentUser.id
]
)
// Show appropriate UI to the user
showErrorAlert(message: ErrorKit.userFriendlyMessage(for: error))
}Uygulamana ekleyebilecegin ornek genel hata isleme fonksiyonu.
Buradaki sihir groupingID(for:) fonksiyonunda. Hatanin tur yapisi ve enum case’lerine dayali, dinamik parametreleri ve lokalize mesajlari gormezden gelen kararli bir tanimlayici uretiyor.
Bu, ayni temel nedene sahip hatalarin – spesifik detaylar (dosya yollari veya kullanici ID’leri gibi) farkli olsa bile – ayni gruplama ID’sine sahip olacagi anlamina geliyor:
// Both generate the same groupID: "3f9d2a"
ProfileError
└─ DatabaseError
└─ FileError.notFound(path: "/Users/john/data.db")
ProfileError
└─ DatabaseError
└─ FileError.notFound(path: "/Users/jane/backup.db")Bu yaklasim birkac fayda sagliyor:
Yaygin sorunlari belirleme: En sik hangi hatalarin olustugunu gor
Duzeltimeleri onceliklendirme: Yuksek etkili sorunlara oncelik ver
Cozumu izleme: Duzeltmelerden sonra hata oranlarinin dusup dusmedigini izle
Yeni sorunlari tespit etme: Surum sonrasi yeni hata kaliplarini hizla belirle
Kullanici segmentleriyle iliskilendirme: Bazi hatalarin belirli kullanicilari etkileyip etkilemedigini gor
Maksimum Icgoru Icin Her Iki Yaklasimi Birlestir
Guclu bir yaklasim, otomatik analitigi kullanici tarafindan baslatilan geri bildirimle birlestirmek – yani soyle bir sey yapabilirsin:
func handleError(_ error: Error) {
// Always track for analytics
trackErrorAnalytics(error)
// For serious or unexpected errors, prompt for feedback
if isSerious(error) {
showErrorAlert(
message: ErrorKit.userFriendlyMessage(for: error),
feedbackOption: true
)
} else {
// For minor issues, just show a message
showErrorAlert(message: ErrorKit.userFriendlyMessage(for: error))
}
}
func showErrorAlert(message: String, feedbackOption: Bool = false) {
// Implementation of an alert that optionally includes a
// "Send Feedback" button that opens the mail composer with logs
}Bu, su kapsamli sistemi olusturuyor:
Tum hatalar analitik icin izleniyor, genis kaliplari gormeni sagliyor
Ciddi hatalar kullanicilari loglarla birlikte detayli geri bildirim icin yonlendiriyor
Kullanicilar izleyemeyecegin sorunlar icin her zaman geri bildirim baslatabiliyor
Loglama Icin En Iyi Pratikler
Log toplamanin degerini en ust seviyeye cikarmak icin su en iyi pratikleri dikkate al:
1. Baglam Icin Loglari Yapilandir
Loglarinda neler oldugunu anlamak icin yeterli baglam sagla:
// Instead of:
Logger().error("Failed to load")
// Use:
Logger().error("Failed to load document \(documentId): \(ErrorKit.errorChainDescription(for: error))")2. Uygun Log Seviyelerini Sec
Ayrintililik seviyesini kontrol etmek icin log seviyelerini stratejik kullan:
.debug– sadece gelistirme sirasinda gereken gelistirici detaylari icin.info– normal uygulama akisini izlemek icin.notice– kullanicilarin onemseyecegi onemli olaylar icin.error– duzeltilmesi gereken ama temel islevselligi engellemeyen sorunlar icin.fault– temel islevselligi bozan kritik sorunlar icin
3. Hassas Bilgileri Koru
Kullanici verilerini korumak icin gizlilik duzenleyicileri kullan:
Logger().info("Processing payment for user \(userId, privacy: .private)")4. Onemli Kullanici Eylemlerini Logla
Hatalara giden yolu anlamak icin kullanici etkinliginden iz birakmalar olustur:
Logger().notice("User navigated to profile screen")
Logger().info("User tapped edit button")
Logger().notice("User saved profile changes")5. Onemli Islemlerin Baslangic ve Tamamlanmasini Logla
Tamamlanmamis gorevleri belirlemek icin onemli islemleri cifte paranteze al:
Logger().notice("Starting data sync")
// ... sync implementation
Logger().notice("Completed data sync")Destek ve Gelistirme Uzerindeki Etkisi
Bu araclari uygulamak hem kullanici deneyimini hem de gelistirme is akislarini donusturebilir:
Kullanicilar Icin:
Basitlestirilmis Raporlama: Tek dokunusla geri bildirim gonder
Teknik Soru Yok: Sinir bozucu ileri-geri iletisimden kacin
Daha Hizli Cozum: Sorunlar daha hizli teshis edilip duzeltilir
Daha Iyi Deneyim: Kullanicilara sorunlarini ciddiye aldigini gosterir
Gelistiriciler Icin:
Tam Baglam: Sorunlar olustugunda tam olarak neler oldugunu gor
Azaltilmis Destek Suresi: Ek bilgi istemek icin daha az zaman harca
Daha Iyi Yeniden Uretim: Log verilerine dayali daha guvenilir yeniden uretim adimlari
Verimli Hata Ayiklama: Hata raporlarindaki kaliplari hizla belirle
Veriye Dayali Onceliklendirme: En yaygin sorunlari duzeltmeye odaklan
Sonuc
ErrorKit’in yaklasimi, bir kullanicinin “calismiyor” demesi ile gercekte ne oldugunu bilmek arasindaki sinir bozucu boslugu kopruluyor. Otomatik log toplamanin akilli hata analitigiyle birlestirilmesinin gercekten ise yarayan bir geri bildirim dongusu olusturdugunu gordum.
Gercekten guclu olan sey, kullanicilar sorunlari bildirmeyi sectiklerinde detayli loglar alirken ayni zamanda hic bahsetmedikleri sorunlari da yakalamak. Bu cift tarafli yaklasim, uygulamalarimdaki sorunlari anlama ve duzeltme seklimi donusturdu. Eger sorunlari gozleri bagli ayiklamaktan biktiysan, ErrorKit tum bu loglama araclarini ve hata yonetimi iyilestirmelerini iceriyor – bunlar kendim ihtiyac duydugum icin gelistirdigim araclar:
Kullanici geri bildirimi ve hata raporlamayi nasil yonetiyorsun? Gercekten ise yarayan baska etkili teknikler buldun mu? Sosyal medyada (asagidaki linklerden) bana bildir!

