Tüm Yazılar
KategoriiOS
Okuma Süresi
15 dk
Yayın Tarihi
2026-06-22
Kelime Sayısı
3.273kelime

Kahveni hazırla - bu içerikli bir makale!

App Intents iOS 27: LongRunningIntent ve Yeni Siri Rehberi

Özet

iOS 27 App Intents LongRunningIntent SyncableEntity Siri entegrasyonunu WWDC26 Session 345 kaynaklarıyla anlatan, 30 saniyelik sınırı aşma ve cihazlar arası Siri konuşmasını kapsayan rehber.

App Intents iOS 27: LongRunningIntent ve Yeni Siri Rehberi

iOS 27 App Intents framework'üne WWDC26'nın 345 numaralı oturumuyla önemli bir güncelleme getirdi: LongRunningIntent, CancellableIntent, EntityCollection ve SyncableEntity gibi yeni API'ler, artık Siri entegrasyonlarını hem daha dayanıklı hem de cihazlar arası tutarlı hale getiriyor. Bu rehberde iOS 27 App Intents LongRunningIntent SyncableEntity Siri entegrasyonu konusunu, WWDC26 Session 345 ve Apple'ın resmi API dokümantasyonu üzerinden, beta dönemi (Haziran 2026) itibarıyla neyin gerçekten değiştiğini göstererek anlatıyorum.

💡 Pro Tip: Mevcut bir AppIntent'i LongRunningIntent'e taşırken önce perform() gövdeni performBackgroundTask bloğuna al — protokolü eklemeden önce bu refactor'ı tek başına test etmek, hangi hatanın hangi değişiklikten geldiğini ayırmanı kolaylaştırır.

İçindekiler

iOS 27'de App Intents neden yeniden önemli oldu

App Intents framework'ünün temel vaadi hiç değişmedi: uygulamanın içeriğini ve eylemlerini Apple Intelligence, Siri, Spotlight, Shortcuts ve widget'lar gibi sistem deneyimleri için keşfedilebilir kılmak. WWDC26 Session 345, oturumdaki ifadeyle "our 2027 releases" ile gelen yenilikleri sekiz başlıkta anlatıyor; dokümantasyon aynı API'leri "iOS 27.0" etiketiyle listeliyor. Bu başlıklardan üç ana eksene odaklanıyorum: uzun süren işlerin artık kesintiye uğramadan tamamlanabilmesi, büyük veri kümeleriyle çalışırken performans kaybı yaşanmaması ve entity'lerin cihazlar arasında tutarlı kalması. Bu üç eksen sırasıyla LongRunningIntent, EntityCollection ve SyncableEntity ile karşılık buluyor; bunları CancellableIntent ve RelevantEntities ile birlikte beş çekirdek API olarak işliyorum, son bölüm ise ExecutionTargets ve @UnionValue'ya ayrılıyor.

Halihazırda App Intents temellerine hiç değinmediysen önce App Intents ve Shortcuts entegrasyonu yazısını okumanı öneririm — bu rehber o temelleri tekrar etmiyor, doğrudan iOS 27 deltasına odaklanıyor.

LongRunningIntent ile 30 saniyelik duvarı aşmak

Apple'ın resmi dokümantasyonuna göre LongRunningIntent, "an interface you use to extend the background execution time of an app intent that performs a long-running task" olarak tanımlanıyor. Sorunun kaynağı şu: sistem normal bir intent'e geleneksel olarak yalnızca 30 saniyeye kadar çalışma süresi tanıyor ("the system traditionally gives it up to 30 seconds to finish its task"). Fotoğraf toplu işleme, büyük dosya aktarımı veya çok adımlı bir otomasyon gibi işler bu sürede bitmeyebilir — WWDC26 oturumunda Apple ekibi bunu tam olarak "the intent kept failing because it couldn't finish within the 30-second limit" cümlesiyle açıklıyor.

LongRunningIntent, Swift tarafında ProgressReportingIntent'i genişleten bir protokol (protocol LongRunningIntent : ProgressReportingIntent). ProgressReportingIntent aslında yeni bir API değil — iOS 17.0'dan beri var; iOS 27'nin katkısı, bu ilerleme raporlama altyapısını arka plan çalışma süresini uzatan LongRunningIntent ile birleştirmesi.

swift
1import AppIntents
2 
3struct SyncPhotoLibraryIntent: LongRunningIntent {
4 static var title: LocalizedStringResource = "Fotoğrafları Senkronize Et"
5 
6 func perform() async throws -> some IntentResult & ReturnsValue<String> {
7 let batches = loadBatches()
8 
9 let summary = try await performBackgroundTask {
10 progress.totalUnitCount = Int64(batches.count)
11 for (index, batch) in batches.enumerated() {
12 try Task.checkCancellation()
13 try await syncBatch(batch)
14 progress.completedUnitCount = Int64(index + 1)
15 }
16 return "\(batches.count) grup senkronize edildi"
17 }
18 
19 return .result(value: summary)
20 }
21 
22 private func loadBatches() -> [[String]] { [] }
23 private func syncBatch(_ batch: [String]) async throws {}
24}

İşin çalıştığı süre boyunca sistem, ilerleme raporu geldikçe otomatik olarak bir Live Activity gösteriyor ve kullanıcı bu Live Activity üzerinden işi durdurabiliyor; iOS 27'nin farkı bu Live Activity'nin App Intents tarafından otomatik tetiklenmesi. Mekaniğin kendisini daha detaylı görmek istersen interaktif widget'lar ve Live Activity yazısına bakabilirsin.

Live Activity'ye ilerleme yazmak: progress nesnesini doğru kullanmak

LongRunningIntent'in en pratik yanı, elle bir ActivityKit implementasyonu kurmana gerek kalmaması. Bunu sağlayan şey ProgressReportingIntent'ten miras alınan progress nesnesi: totalUnitCount ve completedUnitCount alanlarını güncellediğinde sistem bu değerleri Live Activity'ye otomatik yansıtır.

Burada dikkat etmen gereken nokta, progress güncellemesinin sıklığı. Her tek kaydı işledikten sonra güncelleme yapmak yerine, anlamlı aşama sınırlarında (örneğin her toplu işlem grubunda) güncelleme yapmak, hem sistemin gereksiz yeniden çizim yapmasını önler hem de kullanıcıya daha akıcı bir ilerleme deneyimi sunar:

swift
1import AppIntents
2 
3struct ProcessRecordsIntent: LongRunningIntent {
4 static var title: LocalizedStringResource = "Kayıtları İşle"
5 
6 func perform() async throws -> some IntentResult & ReturnsValue<Int> {
7 let items = Array(1...250)
8 
9 let processedCount = try await performBackgroundTask {
10 progress.totalUnitCount = Int64(items.count)
11 var processed = 0
12 
13 for start in stride(from: 0, to: items.count, by: 25) {
14 let chunk = items[start..<min(start + 25, items.count)]
15 try await process(Array(chunk))
16 processed += chunk.count
17 // Her 25 kayıtta bir güncelle, her kayıtta değil.
18 progress.completedUnitCount = Int64(processed)
19 }
20 return processed
21 }
22 
23 return .result(value: processedCount)
24 }
25 
26 private func process(_ chunk: [Int]) async throws {}
27}

İş iptal edildiğinde devreye CancellableIntent bölümünde anlatacağım onCancel bloğu giriyor.

CancellableIntent: iOS 27'nin değil, iOS 26.4'ün doğal partneri

CancellableIntent, Apple'ın resmi API metadata'sına göre iOS 27 ile değil, iOS 26.4 ile tüm platformlarda tanıtıldı. WWDC26 Session 345'te bu protokol yeniden gündeme geldi çünkü LongRunningIntent'in doğal tamamlayıcısı olarak öne çıkarıldı — uzun süren bir iş artık iptal edilebilir hale de gelmesi gerekiyordu.

Resmi tanım şöyle: "An interface to support the graceful cancellation of your app intent's task." Kullanım şekli, withIntentCancellationHandler(operation:onCancel:isolation:) metoduyla işin ana gövdesini sarmalamak. Metodun onCancel parametresi (IntentCancellationReason) -> Void tipinde, yani iptal nedenini doğrudan sana veriyor:

swift
1import AppIntents
2 
3struct SyncLibraryIntent: AppIntent, ProgressReportingIntent, CancellableIntent {
4 static var title: LocalizedStringResource = "Kütüphaneyi Senkronize Et"
5 
6 func perform() async throws -> some IntentResult & ProvidesDialog {
7 let batchCount = 8
8 
9 return try await withIntentCancellationHandler {
10 progress.totalUnitCount = Int64(batchCount)
11 for index in 0..<batchCount {
12 try await syncBatch(index)
13 progress.completedUnitCount = Int64(index + 1)
14 }
15 return .result(dialog: "\(batchCount) grup senkronize edildi")
16 } onCancel: { reason in
17 // Nedene göre temizlik yap.
18 switch reason {
19 case .timeout: cleanupPartialSync(reason: "timeout")
20 case .userCancelled: cleanupPartialSync(reason: "user_cancelled")
21 default: cleanupPartialSync(reason: "unknown")
22 }
23 }
24 }
25 
26 private func syncBatch(_ index: Int) async throws {}
27 private func cleanupPartialSync(reason: String) {}
28}

WWDC26 oturumundaki anlatıma göre iptal üç farklı kaynaktan gelebilir: "whether the person tapped cancel, the system timed out or needed to reclaim resources". Nedeni ayırt etmek için kendi state'inde ayrı bir takip tutmana gerek yok; dokümantasyonun ifadesiyle "If you want to know the reason for cancellation, use the withIntentCancellationHandler(operation:onCancel:isolation:) method that this protocol offers instead". Handler'a gelen IntentCancellationReason değeri bu bilgiyi taşır ve yukarıdaki gibi .timeout ile .userCancelled arasında ayrım yapabilirsin.

EntityCollection ile büyük veri kümelerinde ölçek

Normal bir @Parameter dizisi kullandığında sistem, intent çalışmadan önce dizideki her entity'yi tam olarak resolve eder — yani ilgili query'yi çağırıp entity'nin tüm property'lerini doldurur. Yüzlerce ya da binlerce kayıtla çalışan bir intent'te bu, gözle görülür bir gecikme yaratır.

EntityCollection, Apple'ın resmi dokümantasyonunda "an array of entity identifiers that you use to improve the efficiency of operations involving large numbers of entities" olarak tanımlanıyor. Tip imzası struct EntityCollection<Entity> where Entity : AppEntity şeklinde ve iOS 27.0 ile geldi. Parametre tipini buna çevirdiğinde sistem yalnızca entity kimliklerini taşır, tam resolve işlemini intent'in kendisine bırakır:

swift
1struct BatchTagPhotosIntent: AppIntent {
2 static var title: LocalizedStringResource = "Fotoğrafları Etiketle"
3 
4 @Parameter(title: "Fotoğraflar")
5 var photos: EntityCollection<PhotoEntity>
6 
7 func perform() async throws -> some IntentResult {
8 // photos burada henüz tam resolve edilmemiş kimlik listesi;
9 // yalnız ihtiyacın olan alt kümeyi kendin resolve edersin.
10 for identifier in photos.identifiers {
11 try await tagPhoto(id: identifier, tag: "iOS27")
12 }
13 return .result()
14 }
15}

WWDC26 oturumunda Apple ekibi bunu 1000 fotoğrafı bulup etiketleyen bir Shortcut demosu üzerinden gösterdi ve EntityCollection ile sonucu "almost instant" (neredeyse anlık) olarak tanımladı; kesin bir milisaniye ya da yüzde rakamı paylaşılmadı.

SyncableEntity ve cihazlar arası Siri konuşmaları

SyncableEntity, Apple'ın tanımıyla "an interface that indicates your entity has an identifier that's consistent across devices." Protokol imzası protocol SyncableEntity : AppEntity ve iOS 27.0 ile geldi. Kullanım amacı net: "Siri uses this capability to transfer a conversation from one device to another."

Sorun şu senaryoda ortaya çıkıyor: entity ID'n cihaza özgü üretiliyorsa (örneğin yerel bir veritabanı satır kimliği), aynı fotoğraf iPhone'da ve iPad'de farklı ID alır. Siri bir cihazda başlayan bir konuşmayı diğerinde sürdürmek istediğinde bu ID'yi çözemez ve konuşma kopar. Kimliğin zaten cihazlar arası tutarlıysa — örneğin sunucudan aldığın bir UUID — dokümantasyonun ifadesiyle protokolü "without any additional changes" ekleyebilirsin. Yerel ve kararlı kimliği ayrı tutuyorsan entity'nin id property'sinin tipini SyncableEntityIdentifier yaparsın:

swift
1import AppIntents
2 
3struct PhotoEntity: AppEntity, SyncableEntity {
4 // Yerel ID (CoreData satır kimliği) ile kararlı ID (CloudKit
5 // record name) tek bir kimlikte eşleşir.
6 var id: SyncableEntityIdentifier<String, String>
7 var title: String
8 
9 init(localID: String, stableID: String, title: String) {
10 self.id = SyncableEntityIdentifier(local: localID, stable: stableID)
11 self.title = title
12 }
13 
14 static var typeDisplayRepresentation: TypeDisplayRepresentation = "Fotoğraf"
15 static var defaultQuery = PhotoQuery()
16 
17 var displayRepresentation: DisplayRepresentation {
18 DisplayRepresentation(title: "\(title)")
19 }
20}
21 
22struct PhotoQuery: EntityQuery {
23 func entities(
24 for ids: [SyncableEntityIdentifier<String, String>]
25 ) async throws -> [PhotoEntity] { [] }
26}

RelevantEntities ile bağlamsal öneri

RelevantEntities'in iki birincil kaynaktaki çerçevesi aynı genişlikte değil; bunu bilerek kullanman gerekiyor. Oturumdaki tanım geniş: "With RelevantEntities, you can suggest entities to the system and provide context about when and why they're relevant." Resmi dokümandaki özet ise dar: "a type you use to donate your app's songs, albums, artists, and other media items to play during workouts". Beta dönemi itibarıyla AppEntityContext'in belgelenmiş tek bağlam üreticisi de audio(_:), yani donation'ını bir AudioContext ile etiketliyorsun; oturumun örneği koşu çalma listelerini antrenman bağlamına bağlıyor:

swift
1import AppIntents
2 
3func donateRunningPlaylists(
4 dailyRun: PlaylistEntity,
5 runningMix: PlaylistEntity
6) async throws {
7 let playlistEntities = [dailyRun, runningMix]
8 let workoutContext = AppEntityContext.audio(.workout)
9 
10 try await RelevantEntities.shared.updateEntities(
11 playlistEntities,
12 for: workoutContext
13 )
14 
15 // Belirli kayıtları kaldır:
16 try await RelevantEntities.shared.removeEntities(
17 playlistEntities,
18 from: workoutContext
19 )
20 // Ya da hepsini:
21 try await RelevantEntities.shared.removeAllEntities()
22}

Bağlamı daraltmak istersen workout(activityType:) ve workout(intensityLevel:) tip metotları var; oturumun örneği .workout(activityType: .running) yazıyor.

Kaydın, sen removeAllEntities(), removeAllEntities(for:), removeEntities(_:) ya da removeEntities(_:from:) çağırana kadar kalıcı kalır. Medya dışı bir "bağlamsal öneri" senaryosunda oturumun önerdiği ayrım şu: Spotlight'ı içeriğin aranabilir olması, interaction donation'ı sistemin kullanım örüntülerini öğrenmesi, RelevantEntities'i ise belirli durumlarda hangi içeriğin alakalı olduğunu sisteme söylemek için kullan — bunlar aşağıdaki SSS bölümünde ayrıca ele alınıyor.

ExecutionTargets: hangi işlem hangi process'te çalışır

Intent'lerin uygulama ve extension'ların ortak kullandığı bir pakette yaşadığında sistem hangi process'in çalıştıracağına sezgisel kurallarla karar veriyor ve bu her zaman doğru process olmuyor. Apple ekibinin oturumdaki tanımı: "ExecutionTargets lets you tell the system exactly which process should run your intent." Hedef olarak ana uygulamayı, bir App Intents extension'ını, bir WidgetKit extension'ını ya da bunların herhangi bir bileşimini seçebilirsin — örneğin veri yazan bir widget düğmesinin intent'ini ana uygulamada tutmak gibi.

Aynı şekilde @UnionValue da oturum kaynaklı: "A Swift enum where each case wraps a different type, letting a single parameter represent one of several options." Makro, bir parametrenin birden fazla entity tipinden birini kabul etmesini sağlıyor; kullanımı widget'larla da sınırlı değil: "this isn't limited to Widgets — @UnionValue parameters work everywhere your intent does, including the Shortcuts app". Oturumun ifadesiyle makronun ürettiği şey, sistemin ihtiyaç duyduğu tip bilgisi, case metadata'sı ve picker desteği.

swift
1@UnionValue
2enum MediaSelection {
3 case song(SongEntity)
4 case album(AlbumEntity)
5 case podcast(PodcastEntity)
6 
7 static let typeDisplayRepresentation: TypeDisplayRepresentation = "Medya"
8 static let caseDisplayRepresentations: [Cases: DisplayRepresentation] = [
9 .song: "Şarkı",
10 .album: "Albüm",
11 .podcast: "Podcast"
12 ]
13}
14 
15struct PlayMediaIntent: AppIntent {
16 @Parameter(title: "Medya")
17 var selection: MediaSelection
18 
19 func perform() async throws -> some IntentResult {
20 switch selection {
21 case .song(let song): try await play(song)
22 case .album(let album): try await play(album)
23 case .podcast(let podcast): try await play(podcast)
24 }
25 return .result()
26 }
27}

Mevcut AppIntent'leri iOS 27'ye taşırken izlenecek sıra

Aşağıdaki sıra, yukarıdaki API sözleşmelerinden çıkardığım pratik bir uygulama sırası:

  1. Önce süreyi ölç. perform() gövden 30 saniyeyi düzenli aşıyorsa LongRunningIntent adayıdır; aşmıyorsa değiştirmene gerek yok. Ölçümü gerçek cihazda, gerçek veri hacmiyle yap — simülatör süreleri yanıltıcı olabilir.
  2. `performBackgroundTask` sarmala. Mevcut mantığını değiştirmeden bu closure'a taşı ve progress alanlarını doldur. Adımı tek başına test etmek, sonraki adımda CancellableIntent eklerken çıkacak hataları ayrıştırmanı kolaylaştırır.
  3. `CancellableIntent` ekle ve gerçek bir `onCancel` yaz. Boş bırakma — kullanıcı durdurduğunda uygulamanın tutarsız kalmaması bu bloğa bağlı. Kısmi işlenmiş kayıtları geri alacak mısın, olduğu yerde mi bırakacaksın — kararı burada netleştir.
  4. Dizi parametrelerini gözden geçir. Onlarca kayıttan fazlasını taşıyan her @Parameter dizisi EntityCollection adayıdır; önce intent'inin tam property setine mi yoksa yalnızca kimliğe mi ihtiyaç duyduğunu netleştir.
  5. Cihazlar arası kullanılan entity'lere `SyncableEntity` ekle, özellikle Siri konuşmalarının bir cihazda başlayıp diğerinde bittiği senaryolarda. Yerel ID'n zaten kararlıysa (örneğin sunucu tarafından atanmış bir UUID) ek bir eşleme yapmana gerek kalmayabilir; yalnızca cihaza özgü ID'lerin varsa SyncableEntityIdentifier eşlemesi gerekir.
  6. `RelevantEntities`'i belgelenmiş bağlamıyla değerlendir. Genel bir "önerilen içerik" deneyimi arıyorsan Spotlight indekslemeyi ve IntentDonationManager donation akışını da masaya koy.

Tablo: Hangi API hangi problemi çözüyor

API
Çözdüğü problem
iOS sürümü
LongRunningIntent
30 saniyelik arka plan çalışma sınırı
iOS 27.0
CancellableIntent
Zarif iptal ve temizlik
iOS 26.4
EntityCollection
Büyük parametre dizilerinde tam-resolve maliyeti
iOS 27.0
SyncableEntity
Cihazlar arası kararsız entity ID
iOS 27.0
RelevantEntities
Bağlama göre içerik önerisi
iOS 27.0
ExecutionTargets
Intent'in hangi process'te çalışacağı
iOS 27.0
@UnionValue
Tek parametrede birden çok entity tipi
iOS 27.0

Tablo: Migration önceliklendirme kontrol listesi

Belirti
Önerilen API
Öncelik
Intent sık sık 30 saniye zaman aşımına takılıyor
LongRunningIntent + CancellableIntent
Yüksek
Parametre dizisi yüzlerce/binlerce kayıt taşıyor
EntityCollection
Yüksek
Aynı içerik farklı cihazlarda farklı Siri sonucu veriyor
SyncableEntity
Orta
Antrenman/ses bağlamında içerik önerisi eksik
RelevantEntities
Orta
Intent'in hangi process'te çalıştığı belirsiz/gereksiz ağır
ExecutionTargets
Düşük

ALTIN İPUCU

Bu yazının en değerli bilgisi

Bu ipucu, yazının en önemli çıkarımını içeriyor.

Easter Egg

Gizli bir bilgi buldun!

Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?

Okuyucu Ödülü

iOS 27 App Intents geçişine başlamadan önce üzerinden geçmen gereken pratik bir kontrol listesi hazırladım. Bu liste, yukarıdaki bölümlerde anlatılan beş API'yi hangi sırayla değerlendireceğini ve migration sırasında en sık atlanan adımları özetliyor; yeni bir intent yazmadan ya da mevcut birini taşımadan önce sırayla gözden geçirebilirsin.

SSS

iOS 27'de 30 saniyeden uzun süren bir intent nasıl yazılır?

Intent'ini LongRunningIntent protokolüne uydur — bu protokol aynı zamanda ProgressReportingIntent'e dayanır. İşini performBackgroundTask bloğu içine al ve düzenli aralıklarla progress nesnesini güncelle; dokümantasyona göre bu property'yi düzenli güncellemezsen sistem arka plan süre uzatmasını iptal edip işini erken sonlandırabilir. Çalışma sırasında kullanıcı arayüzünde otomatik bir Live Activity belirir ve üzerinde durdurma seçeneği bulunur.

SyncableEntity nedir, Siri neden cihazlar arası entity'yi bulamıyor?

Varsayılan olarak entity ID'n cihaza özgü üretilmiş olabilir (örneğin yerel bir veritabanı satır kimliği); aynı içerik iPhone'da ve iPad'de farklı ID alır. Siri bir cihazda başlayan konuşmayı başka cihazda sürdürmek istediğinde bu ID'yi çözemez. SyncableEntity protokolünü ekleyip kararlı bir kimlik (sunucu tarafından atanmış veya CloudKit record ID gibi) sağladığında — yerel ve kararlı kimliği ayrı tutuyorsan id property'sinin tipini SyncableEntityIdentifier yaparak — Siri entity'yi tüm cihazlarda aynı şekilde tanır.

EntityCollection ile binlerce kayıt nasıl hızlı işlenir?

Normal bir dizi parametresi kullanıldığında sistem intent çalışmadan önce dizideki her entity'yi tam olarak resolve eder; binlerce kayıtta bu ciddi bir gecikme yaratır. Parametre tipini EntityCollection'a çevirdiğinde sistem yalnızca entity kimliklerini geçirir, tam resolve işlemini yapmaz. Apple'ın kendi 1000 fotoğraflık demosunda bu yaklaşım "neredeyse anlık" sonuç verdi; kesin bir milisaniye rakamı paylaşılmadı.

Uygulamamı iOS 27 Siri'sinde nasıl görünür yaparım?

Oturumun çizdiği ayrım üç tamamlayıcı yol gösteriyor. Birincisi, içeriğini Spotlight'a indekslemek — Siri'nin içeriğini bulup getirmesinin yolu budur. İkincisi, kullanıcı eylemlerini IntentDonationManager ile donate etmek; sistem örüntü öğrenip benzer eylemleri önerir. Üçüncüsü, hiç aranmamış ya da oynatılmamış içerik için RelevantEntities ile "bu içerik şu durumda alakalı" ipucunu vermek.

CancellableIntent kullanmak zorunlu mu, yoksa yalnız LongRunningIntent yeterli mi?

Zorunlu değil ama şiddetle önerilir. LongRunningIntent yalnızca çalışma süresini uzatır; CancellableIntent olmadan kullanıcı işi durdurmak istediğinde uygulaman temizlik yapma fırsatı bulamaz ve yarım kalmış bir durumda kalabilir. WWDC26 oturumunda iki protokol birlikte, doğal bir çift olarak sunuluyor.

RelevantEntities ile genel bir "önerilen içerik" listesi oluşturabilir miyim?

Burada iki kaynak farklı genişlikte konuşuyor, o yüzden temkinli ol. Oturum API'yi genel tarif ediyor ("suggest entities to the system and provide context about when and why they're relevant"), resmi doküman özeti ise şarkı, albüm, sanatçı, çalma listesi ve podcast gibi medya içeriğinden söz ediyor. Medya dışı genel bir öneri deneyimi kuracaksan Spotlight indekslemeyi ve IntentDonationManager donation'ını da hesaba kat.

Güncelleme (Eylül 2026)

Bu rehber beta döneminde yazıldı. Apple 14 Eylül 2026'da iOS 27.0'ı (24A437) ve Xcode 27'yi (27A266a) yayınladı; yukarıda anlatılan API'ler artık beta değil, genel kullanımda. 21 Eylül 2026 itibarıyla iOS 27.2 beta 2 (24B5089g) dağıtımda.

Sonuç

iOS 27'nin App Intents güncellemesi tek bir büyük özellik değil, birbirini tamamlayan beş API'lik bir set: LongRunningIntent ve CancellableIntent uzun işleri güvenilir hale getiriyor, EntityCollection ölçeği çözüyor, SyncableEntity cihazlar arası tutarlılığı sağlıyor, RelevantEntities ise bağlama göre içerik önerisini üstleniyor. Mevcut bir App Intents entegrasyonun varsa önce süre ve ölçek sorunlarını tespit edip yukarıdaki migration sırasını izlemen yeterli.

Temel App Intents kavramlarına henüz aşina değilsen App Intents ve Shortcuts entegrasyonu yazısıyla başla. Live Activity mekaniğini derinlemesine görmek için interaktif widget'lar ve Live Activity yazısı faydalı olacaktır. Siri'nin konuşma tabanlı tarafını merak ediyorsan SiriKit ile sesli entegrasyon yazısına bakabilirsin. iOS 27'nin SwiftUI tarafında nelerin kırıldığını görmek için iOS 27'de State makrosu ve ContentBuilder kırılmaları yazısını, genel geliştirici perspektifi için ise iOS 27 ve Xcode 27 geliştirici rehberi yazısını okuyabilirsin.

Kaynaklar

Etiketler

#App Intents#iOS 27#Siri#LongRunningIntent#SyncableEntity#WWDC26#SwiftUI
Muhittin Çamdalı

Muhittin Çamdalı

Lead Mobile Engineer

12+ yıllık deneyime sahip Lead Mobile Engineer. Swift, SwiftUI, Kotlin ve Flutter ile iOS, Android ve cross-platform mimarilerde uzman. Performanslı ve kullanıcı dostu mobil uygulamalar geliştiriyorum.

iOS Geliştirme Haberleri

Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.

Paylaş

İlgili İçerik