Eski Dost Yeni Yüzüyle, Widget’lar

Çağatay Çitken
Commencis
Published in
5 min readJul 16, 2020
Ana Ekran Widget’ları

Apple geçtiğimiz WWDC 2020 etkinliğinde, radikal değişikliklerle yenilediği Widget sistemini tanıttı. Yeni widget’lar artık 3 farklı boyutta geliyor ve yeni iOS 14 işletim sistemi cihazlarımızda bu widget’ları uygulamalarımızın da olduğu ana ekrana sürükleyip bırakabileceğiz. (Süper!!). Böylece geliştiriciler uygulamalarının kullanıcılarına önemli bilgileri, kullanıcılar uygulamalarını daha açmadan gösterebilecek. Kullanıcılarının ana ekranlarına göz ucuyla bakmaları, kendilerine ulaşması gereken bilgileri almasına yetecek.

Bunun yanında Apple’ın tanıttığı bir başka yenilik Smart Stacks. Smart stack kullanıcıların içine istediği widget’ları koyabildiği ve bu widget’lar arasında gezinebildiği bir yapı. Bu yapı aynı zamanda cihazın yapay zekasını da kullanarak kullanıcı için o an en önemli olan widget’ı öne getirebilme yetisine sahip. Bu karar verme mekanizması zaman, içeriğin ilgisi, lokasyon bilgisi gibi faktörler ile hesaplanmakta. Buna bir örnek vermek gerekirse, diyelim ki her sabah uyandığınızda ilk işiniz hava durumu uygulamasını açıp gün içindeki hava durumunu kontrol etmek olsun. Smart Stack sizin bu davranışınızı öğrenip size sabah ekranınızı açtığınızda hava durumu widget’ını gösterecek. Müthiş bir özellik değil mi?

WidgetKit üstünde konuşmaya başlamadan önce, geliştirme yapabilmek için nelere ihtiyaç duyacağınızdan bahsetmek istiyorum.

  • SwiftUI. Evet, SwiftUI bilgisi gerekiyor. Widget’larınız için hazırlayacağınız bütün arayüzler SwiftUI kullanılarak yazılmalı. UIKit kullanımı mümkün olmamakla beraber, UIKit ile yazılmış ekranları UIViewRepresentable gibi protocol kullanımları ile SwiftUI’a taşımak da işe yaramayacak.
  • iOS 14 (şimdilik beta) kurulu bir Apple cihazı. Bu madde bir zorunluluk olmamakla beraber, bu yazıyı kaleme aldığım zaman için konuşuyorum, XCode 12 beta 1 simülatörleri widget’larınızı widget galerisinde oluşturamamakta. Tam anlamıyla geliştirmenizi tecrübe etmek isterseniz cihazınız olması gerekiyor.
  • XCode 12. Evet, bu da kesinlikle sahip olmanız gereken maddelerden. WidgetKit için XCode’un 12. sürümünde geliştirme yapmalısınız. Bu yazıyı kaleme aldığım zaman içinde XCode 12 Beta 1 sürümü kullandım.

WidgetKit ile geliştirmenizi yapabilmek için sahip olmanız gereken şeyler şimdilik bunlar. Yazının ilerleyen kısımlarında, kod’a çok boğulmadan, Apple’ın taslak kodu üzerinden ilerleyerek widget’ların çalışma yapısını anlatmaya çalışacağım.

Yapmamız gereken ilk şey projemize Widget Extension target’i eklemek olacak. Daha sonra XCode bizim için taslak kodlarıyla bir extension yaratacak. Bu kodlar derlenebilir ve çalıştırılabilir durumda olacaklar.

Uygulamamızı derleyip cihazımızda çalıştırdıktan sonra, ana ekranımıza dönüp boş bir noktaya basılı tutarak uygulamalarımızı düzenleme moduna geçirelim. Sağ üstteki ‘+’ ikonuna tıkladığımızda önümüze widget’ları içeren bir liste çıkacak, en alta indiğimizde uygulamamızı görebiliriz. Uygulamamıza bastıktan sonra sistem bize uygulamızın desteklediği widget tiplerini sunacak, bunlardan en küçüğünü seçip ana ekranımıza koyabiliriz.

Widget’ları iki ana kategoriye ayırabiliriz. Konfigürasyon yapılamayan widget’lar StaticConfiguration ile yaratılan ve içeriği kullanıcı tarafından hiçbir şekilde konfigüre edilemeyen widget’lar. Konfigürasyon yapılabilen widget’lar ise IntentConfiguration ile yaratılıp kullanıcıdan input alarak içeriğini bu inputa göre değiştirebilen widget’lar. Bu yazıda konfigürasyon yapılamayan widget üzerinden anlatıma devam edeceğim çünkü diğeri ile arasında kod olarak çok büyük farklar bulunmuyor.

Anlamamız gereken 3 protocol ve 2 tane view var.

  • Widget Protocol: Bu protocol widget struct’ımız tarafından conform edilmesi gereken protocol. İçerisinde daha önce bahsettiğim konfigürasyonları içerecek bir body bulunuyor. Bu sistem tarafından kullanılacak asıl widget’ımız diyebiliriz.
  • TimelineEntry Protocol: Bu protocol tipini sağlayan struct’ımız widget’ımızın kullanacağı bilgileri içermeli. Ek olarak protocolden gelen zorunlu date bilgisi, taşıdığı bilginin ne zaman gösterilmesi gerektiğini işaret ediyor.
  • TimelineProvider Protocol: Widget’ımız bu protocol’ü sağlayan struct’ı kullanarak kendini zamanı geldiğinde doğru şekilde konfigüre ediyor.
  • PlaceholderView: Bu view widget’ımızın contenti yüklenme aşamasındayken widget içerisinde gösterilecek.
  • EntryView: Bu view ise içinde entry yani bilgiyi bulunduran ve kendini bu bilgiyle dolduran, widgetımızın gerçek arayüzü.

Widget tanımlamamıza hızlıca bakalım.

Ana Widget

Gördüğünüz gibi taslak kodumuzda widget’ımız StaticConfiguration ile yaratılmış. Bu konfigürasyona String olara bir kind yani bir tür tanımlamışız. Burda dikkat etmemiz gereken en önemli konu, tanımladığımız bu türün her bir widget için eşsiz olması, aksi takdirde işletim sistemi aynı türdeki widget’ları birbiriyle karıştırıp, bunlardan sadece bir tanesini gösterecek.

TimelineProvider protocol’ünü sağlamış bir provider ve bir de yükleme ekranlarında gösterilmesi için bir PlaceholderView vermişiz. Completion block’unda ise entry ile yaratılmış asıl widget’larımızda kullanılacak olan EntryView dönülmüş.

Kısaca entry’mize bakalım

Entry Model

Date burada daha önce bahsettiğim gibi protocol tanımlamasından geliyor. Bunun yanına widget’ınızın kullanacağı bilgileri içerecek property’leri kendi kullanacağınız şekilde eklemeniz gerekiyor.

Placeholder and Widget Views

Burada üstünde duracağım bir şey yok. Bahsettiğim gibi kullanılacak olan Placeholder ve EntryView tanımlamalarımız.

Provider

Asıl önemli olan, widget’ımızın karar mekanizması görevi gören Provider’ımız. Öncelikle TimelineProvider protocol’ü içerisinde çalışacağı entry tipini Entry typealias’ı ile görmek istiyor. Daha sonra içini doldurmamız gereken 2 tane fonksiyon bulunmakta. Bunları kısaca inceleyelim.

Snapshot fonksiyonu içerisinde sadece ve sadece MOCK dediğimiz gerçekleri yansıtmayan data’ları bulundurmalı. Burada asla gerçek data kullanmamaya özen göstermeliyiz, çünkü snapshot widget’ımızı geçiş zamanlarında. doldurmak için kullanılacak. Örneğin ana sayfaya koymak için widget seçimi yapılırken.

Timeline fonksiyonu ise, widget’ımızın gerçek data’ları almak için kullanacağı fonksiyon. Kodun büyük görünmesine bakmayın aslında oldukça sade. Asıl önemli olan nokta şu, bu fonksiyonun completion block’unu çağırırken bir veya birden fazla entry kullanara Timeline yaratıp widget’a vermemiz. Bunun yanında vereceğimiz refresh policy yani widget’ın kendini yenileme yöntemi ile widget yeni data’ların gerekip gerekmediğini bilerek bu fonksiyonu çağıracak.

WidgetKit 3 tane kendini yenileme yöntemi tanımlamış.

  • .atEnd Bu yöntemi kullandığımız zaman widget’ımız kendini verilmiş olan entrylerin en sonuncusunun içerdiği date zamanından hemen sonra yenileyecektir.
  • .after(_ date:) Bu yöntemi spesifik bir zamandan sonra widget’ımızın kendini yenilemesi için kullanabiliriz. Örneğin bir borsa bilgisi içeren widget kullanıyor isek, widget’ın kendini borsanın açık olduğu zamanda yenilemesini sağlayabiliriz.
  • .never Bu yöntemi kullanırsak widget’ımız kendini yenilemeyi bırakacaktır. Tekrar yenilemeyi tetiklemek için uygulama içerisinden WidgetCenter reloadTimelines(ofKind:) fonksiyonunu çağırmamız gerekiyor. Buna bir kullanım örneği vermek gerekirse, widget’ınızdaki bilgiler kullanıcının uygulamaya login olmasıyla anlamlı olacak bir duruma geldiyse bu yöntemi kullanabilirsiniz.

Widget’larla Neler Yapamazsınız

Yenilenen widget’ların ne kadar güçlü olduğu konusunda çok konuştuk, ancak değinmem gereken WidgetKit’in yapamadığı(yapmak istemediği?) birkaç ufak detay var.

Bunlardan ilki ve en önemlisi widget’lar Android eşlenikleri gibi çok fazla interaktiflik sunmuyor. Evet artık ortak noktaları biraz daha arttı, ama bir Android geliştiricisi gibi kendinizi özgür hissetmeyin. Apple’ın söylediği şekliyle Widget’lar sadece ve sadece READ-ONLY bilgiler içermeli, kesinlikle buton gibi interaktif arayüz elementleri bulundurmamalı. WidgetKit zaten widget’larınızı yaratırken bu interaktif elementleri otomatik çıkartacak.

Kullanıcıların yapabileceği tek şey widgetlarınız ile sadece üstüne tıklayıp uygulamanıza sizin önceden belirleyebildiğini URL ile yönlenmek olacak. Bu URL’i kullanarak kullanıcıyı uygulama içerisinde anlamlı bir yere taşımak geliştiricilere ve uygulamalarının yapılarına kalmış bir şey.

Widget’lar kısmen konfigüre edilebilir yapıdalar. Bu yapıyı intent yaratarak widget’larınız için sağlayacaksınız. Bu örneğin üstünden geçmeyeceğim çünkü bunun verdiğim örnekten tek farkı widget’ınınzın IntentConfiguration ile oluşturulması ve provider olarak IntentTimelineProvider protocol’ü sağlaması.

Widget‘larınız içinde video oynatamazsınız.

Ancak bütün bunlara rağmen, naçizane fikrim, bu maddeler bir geliştirici için kısıtlayıcı maddeler gibi görünse de, bu maddeler sayesinde Apple widget’larının kendi bağlamlarından çıkmamasını garanti etmiş. Böylelikle widget’lar her zaman yaratılmış oldukları amaç içinde, sadeliklerini koruyarak kullanıcıların huzuruna çıkacak.

Bu yazıyı okuyucuların ellerini WidgetKit ile kirletmeden önce, bir ön bilgi sağlaması amacıyla kaleme aldım. Umarım bu isteğimi başarmışımdır ve sizleri sıkmadan Apple’ın WidgetKit’ine minik de olsa bi giriş yapmışımdır. Geri dönüşlerinizi almaktan mutluluk duyarım.

Sağlıcakla.

--

--