BİL209U-MOBİL UYGULAMA GELİŞTİRME
Ünite 8: Örnek Mobil Uygulama Geliştirme
Giriş
Bu ünitede kitapta daha önceki ünitelerde öğrenilen konuları pekiştirmek amacıyla baştan sona bir flutter uygulaması gerçekleştirilecektir. Bu uygulamada kullanıcı girişinin olduğu ve verilerin bir Firebase veritabanında saklandığı telefon defteri uygulaması yapılacaktır. Ayrıca son olarak sensor kullanımına örnek olması açısında telefon defterindeki kişinin telefonu sallama yöntemiyle aranabilmesi sağlanacaktır. Telefon defteri uygulamasında kullanıcı girişi olacak online Firebase Cloud Firestore veritabanı kullanacaktır. Dolayısıyla kullanıcı istediği telefondan giriş yaptığında daha önce başka bir telefondan oluşturduğu kişilerine erişim sağlayabilecektir. Öncelikle veritabanı olarak Firebase seçilmiştir. Bunun birkaç sebebi bulunmaktadır. Flutter, Firebase gibi Google’nin bir ürünüdür ve Firebase’yi doğal olarak desteklemektedir. Dolayısıyla kullanıcı girişi gibi nispeten karmaşık olabilecek ve çeşitli güvenlik tedbirlerinin alınmasını gerektirecek durumlar için hazır araçları bulunmakta ve çok kolaylıkla uygulanabilmektedir. Firebase proje geliştirirken ve küçük çaplı kullanımlarda ücretsiz olarak kullanılabilmektedir. Örneğin veritabanı için 1 GB’a kadar olan kullanımlar ücretsizdir. 1 GB’in geçilmesi durumunda ücret ödenmesi gerekmektedir. 1 GB’ın oldukça makul bir değer olduğu ve çeşitli optimizasyon teknikleri kullanıldığında birçok projede 1 GB’ın üzerinde çıkmak gerekmeyeceği söylenebilir. Ayrıca kullanıcı girişinde ise aylık 10.000 girişe kadar ücretsizdir. Sonrasında ise ücret talep edilmektedir. Firebase dışında farklı çözümlerin tercih edilmesi durumunda da mutlaka bir ücret ortaya çıkacaktır. Örneğin veritabanını kendi sunucumuzda barındırmamız durumunda, sunucu kiralama ücreti, alan adı ücreti gibi çeşitli ücretlerle karşılaşılması normaldir. Bu durumda yapılması gereken şudur, aylık kullanım miktarları tahmin edilerek, en uygun (ucuz, kullanımı kolay ve güvenli) çözümün uygulanmasıdır. Firebase’de bu çözümlerden biri olabilir. Bu ünitede projede yazılan tüm kodlar burada verilmemiştir. 100’lerce satır kod yazıldığı için tüm kodların burada verilmesi uygun olmayacaktır. Onun yerine kritik öneme sahip olan kodlara yer verilmiş ve açıklamaları yapılmıştır. Projenin kaynak kodları aşağıdaki bağlantıdan indirilebilir.
Kaynak kodlara;
https://serkancankaya.com/FlutterTelDefteri_Kaynak_Kod lar.zip
adresinden ulaşabilirsiniz.
Fırebase Veri Tabanının Kurulması
Firebase veri tabanını kullanabilmek için öncelikle Google hesabının olması gerekmektedir. Daha sonra firebase.google.com adresine Google hesabı ile giriş yaptıktan sonra Goto Console seçeneğine tıklanmalıdır. Burada yeni proje oluşturulabilir veya daha önce oluşturulmuş projeler düzenlenebilir. Yeni proje oluşturmak için “Add Project” seçeneği seçilmelidir. İki aşamalı proje oluşturma sayfasında ilk olarak proje adı
belirlenmelidir. Eğer proje adı daha önce başka bir kullanıcı tarafından alınmış ise Firebase proje adı ile başlayan eşsiz bir isim üretmektedir. Örneğimizde FlutterTelDefteri ismi kullanılmıştır. Bu isim daha önce başka bir kullanıcı tarafından kullanılmadığı için eşsiz isim olarak kabul edilmiş ve yeni eşsiz bir isim üretme durumu olmamıştır. İkinci aşamada “Google Analytics for your Firebase Project” araçlarını kullanılıp kullanılmayacağı sorulmaktadır. Bu örnekte bu seçenek iptal edilerek devam edilmiştir. Böylece Firebase projesi oluşturulmuş olur.
Proje oluşturulduktan sonra bu bölümde yapılması gereken iki işlem bulunmaktadır: Authentication ve Firestore Database (Cloud Firestore). Authentication geliştirilecek uygulamada kullanıcı girişlerini yönetmek için kullanılan modüldür. Authentication bölümünden Get Started seçeneği seçilmelidir. Firebase kullanarak farklı sistemler ile kullanıcı girişi yapılabilmektedir. Bu projede Email/Password seçeneği kullanılmıştır. Kullanıcılar e-Posta adreslerini kullanarak şifrelerini oluşturmuşlardır. Farklı projelerde diğer kullanıcı girişi seçenekleri de değerlendirilebilir. Kullanıcılar açısından internetteki en büyük problemlerden biri de çok sayıda platforma üye olmak ve bu platformların şifrelerini hatırlamaktır. Alternatif kullanıcı giriş seçenekleri sayesinde kullanıcılar yeni şifre belirlemek zorunda kalmadan örneğin Google hesabı ile sisteme giriş yapabilirler. Ayrıca birden fazla giriş seçeneğinin aynı anda kullanılması da mümkünüdür. Örneğin uygulamalar hem Google hem de Apple ile kullanıcı girişi yapabilecek şekilde yapılandırılabilir. Böylece kullanıcılar için farklı kullanıcı girişleri arasından tercih yapabilecekleri bir esneklik sunulmuş olacaktır.
Bu çalışmada sadece Email/Password seçeneği tercih edilmiştir. Dolayısıyla kullanıcıların uygulama öncelikle üyelik oluşturması gerekecektir. Uygulamaya kayıtlı kullanıcıların yönetim işlemleri de yine Authentication bölümündeki Users sekmesinden yapılmaktadır. Bu bölüm kullanılarak yeni kullanıcı oluşturulabilir. Böylelikle uygulama geliştirilirken kullanıcı girişi sayfaları test edilebilecektir. Ayrıca kullanıcı silme, pasif duruma alma ve kullanıcının şifresini sıfırlama işlemleri de yapılabilmektedir. Authentication bölümündeki Templates sekmesinde e-Posta adres doğrulama, şifre sıfırlama, e-Posta adresi değiştirme gibi e-Posta iletileri ayarlanabilmektedir. Ayrıca bu bölümde SMTP ayarının da yapılması gerekmektedir. Böyleye gönderilecek e-Postalar burada ayarlanan SMTP e-Posta sunucusu tarafından gönderilebilecektir. Buraya kurumsal mail sunucusunun adresi yazılabileceği gibi Gmail gibi bir sunucunun da adresi ve kullanıcı bilgileri yazılabilir. Ancak Gmail gibi ücretsiz e-Posta sunucuları ile günlük gönderilebilecek e-Posta sayısı sınırlıdır. Bu durumda günlük gönderilecek e-Posta sayısı örneğin Gmail için 500’ü geçiyorsa ücretli üyelik satın almak veya farklı e-Posta sunucuları kullanmak gerekecektir. Firestore Database bölümünde Create Database ile veritabanı oluşturulmalıdır. Projede öncelikle test mode kullanılmıştır (Görsel 8.3). Ancak bu mod güvenli değildir. Proje bittikten sonra daha uzun
kullanımlara yönelik olarak veritabanına erişim kuralları güncellenmelidir. Bir sonraki aşamada veritabanının hangi coğrafi bölgede barındırılacağı seçildikten sonra Enable ile veritabanı kullanıma hazır hale gelecektir. Uygulamanın hedef kitlesinin bulunduğu coğrafi bölgeye yakın bir yer seçilmesi durumunda performansın daha iyi olacağı söylenebilir. Bu çalışmada Türkiye’ye yakın olması bakımından Avrupa merkezli bir sunucu tercih edilmiştir. Firebase Cloud Firestore klasik veri tabanlarından farklı yapıda bir veritabanı sistemidir. Detaylı bilgi için kendi web sayfasındaki yardım belgeleri incelenebilir. Veritabanı oluşturulduktan sonra kişilerin telefon ve e-Posta bilgilerini barındırmak için bir koleksiyon oluşturulmalıdır. Bu örnekte defter isminde bir koleksiyon oluşturulmuştur (Görsel 8.4). Aslında koleksiyon oluşturulmadan da uygulamanın çalışacağı söylenebilir. Cloud Firestore koleksiyonlar ilk kullanıldıkları anda otomatik olarak oluşturulmasını sağlamaktadır.
Böylece veritabanı ile ilgili süreçler bitmiştir. Bundan sonra yeni kullanıcı kaydı, kullanıcı girişi, veritabanına yeni kayıt ekleme, düzenleme ve silme işlemleri flutter projesi ile gerçekleştirilecektir. Öncelikle bu bölümde Cloud Firestore hakkında biraz bilgiye yer verilmiştir.
Cloud Firestore
Cloud Firestore, NoSQL türünde belge odaklı bir veritabanıdır. NoSQL veritabanları ilişkisel veritabanı yönetim sistemlerinden farklı olarak verilerin tablo şeklinde depolanmadığı veri tabanlarıdır. NoSQL veritabanları, veri modellerine göre çeşitli türlerde olabilmektedir. Bu türler ise belge, anahtar/değer çifti, geniş sütun ve grafik şeklinde sıralanabilir. NoSQL veritabanları esnek şemalar sağlarlar ve büyük miktarda veri ve yüksek kullanıcı yükleriyle kolayca ölçeklenirler. Cloud Firestore veritabanında da tablo veya satır yoktur. Bunun yerine, verileri koleksiyonlar halinde düzenlenen belgelerde depolanır. Her belge bir dizi anahtar/değer çiftini içerir. Tüm belgeler koleksiyonlarda saklanmalıdır. Belgeler, her ikisi de dizeler gibi ilkel alanlar veya listeler gibi karmaşık nesneler içerebilen alt koleksiyonlar ve iç içe nesneler içerebilir. Koleksiyonlar ve belgeler, Cloud Firestore’da dolaylı olarak oluşturulur. Cloud Firestore’da depolama birimi belgedir. Belge, değerlerle eşleşen alanları içeren bir kayıt olarak düşünülebilir. Ancak belgeler koleksiyonları da içerebileceği için kayıttan daha fazlasıdır. Her belge bir adla tanımlanır. Örneğin ali kullanıcısını temsil eden bir belge şöyle olabilir: ali adi : “Ali” soyadi : “Veli” dogum_tarihi : 1815 Bu örnekte görüldüğü gibi belgeler anahtar/değer çiftlerini barındırabilmektedir. Burada adi anahtar “Ali” ise onun değeridir. Bir belgedeki karmaşık, iç içe nesnelere map denir. Örneğin, yukarıdaki örnekteki kullanıcının adı aşağıdaki gibi bir map ile yapılandırılabilir. ali isim: adi : “Ali” soyadi : “Veli” dogum_tarihi : 1815
Görüldüğü üzere bu yapı JSON’a çok benzemektedir. Aslında temelde de Cloud Firestore’un bir tür JSON veritabanı olduğu da söylenebilir. Belge adları bu örnekte
olduğu gibi elle verilebileceği gibi, Cloud Firestore tarafından otomatik, eşsiz bir değer olarak üretilebilmektedir. 4ly08ultXbrbDNuyeev8 değeri Cloud Firestore tarafından üretilmiş örnek bir değerdir. Belgeler, yalnızca belgeler için kapsayıcı olan koleksiyonlarda yaşar. Örneğin, her biri bir belgeyle temsil edilen çeşitli kullanıcılarınızı içeren bir kullanıcı koleksiyonu olabilir: kullancilar HNjhUdlUO88olr0MHwl7 adi : “Ali” soyadi : “Veli” dogum_tarihi : 1995 4ly08ultXbrbDNuyeev8 adi : “Hasan” soyadi : “Hüseyin” dogum_tarihi : 2000
Örnekte kullanıcılar koleksiyonunda iki belge bulunmaktadır. Bu belgelerde ise kullanıcılara ait bilgiler yer almaktadır. Cloud Firestore şemasız olduğu için belgelere hangi alanların konulacağı ve bu alanlarda hangi veri türlerinin saklanacağı konusunda herhangi sınırlama bulunmamaktadır. Aynı koleksiyondaki belgelerin tümü farklı alanlar ve veri türleri içerebilir. Ancak, klasik tablolarda olduğu gibi belgeleri daha kolay sorgulayabilmek için aynı alan ve veri türlerini ilgili koleksiyonda bulunan tüm belgede kullanmak mantıklı olacaktır. Bir koleksiyonda sadece belgeler bulunabilir. Koleksiyonlarda doğrudan değer saklamak mümkün değildir. Ayrıca koleksiyonlar diğer koleksiyonları da içeremez. Firebase’de alt koleksiyon oluşturmak mümkündür. Alt koleksiyon, belirli bir belgeyle ilişkili bir koleksiyondur. Bir başka deyişle belgelerin altında alt koleksiyon oluşturulabilir. Örneğin kullanıcı ile ilgili belgenin içinde notlar alt koleksiyonu oluşturulabilir. Notlar koleksiyonunun içinde de o kullanıcının yazmış olduğu notlardan oluşan belgeler bulunabilir. kullancilar HNjhUdlUO88olr0MHwl7 adi : “Ali” soyadi : “Veli” dogum_tarihi : 1995 notlar KAj7jGqPxTZCghRvw5VS baslik : “Ders Çalış” mesaj : “C++ ilgili ders çalışmam lazım” KbYWG1wCAf9ttiYBIVZK baslik : “Proje” mesaj : “Proje başvurusu hazırlamam lazım.”
Böylece bu notlar sadece Ali Veli isimli kullanıcıya ait olmuş olur. Bir koleksiyon içindeki belgelerin adları benzersizdir. Koleksiyonların oluşturulmasına veya silinmesine gerek yoktur. Bir koleksiyondaki ilk belge oluşturulduktan sonra koleksiyon var olur. Bir koleksiyondaki tüm belgeler silinirse, koleksiyonda silinmiş olur. Sonuç olarak Firebase Cloud Firestore sistemi yaygın kullanılan RDBMS’lerden çok farklıdır. Ancak kolay kullanımı ve yüksek performanslı olması bakımından avantajları bulunmaktadır. Spark isminde ücretsiz bir planı olmasına rağmen, çok yoğun kullanımlarda ciddi kullanım ücretleri ortaya çıkabilir. Geliştiriciler, gereksinimlerini tespit ederek, Firebase veya MySQL, PostgreSQL, Oracle, SQL Server gibi RDBMS’lerden birini tercih edebilirler. Farklı sistemlerin avantaj ve dezavantajları bulunmaktadır. Örneğin MySQL açık kaynak kodludur ve ücretsiz olarak kullanılabilir. Ancak MySQL’i kurabilmek için bir alan adı ve sunucuya ihtiyaç vardır. Alternatif olarak bulut sistemler üzerinde barındırılan veritabanı sistemlerinden de yararlanılabilir. Doğal olarak bulut sistemlerin, alan adı ve sunucu hizmetinin de bir maliyeti olacaktır.
Telefon Defteri Uygulamasının Sayfalarını Tasarlama
Flutter projesi oluşturmak için çeşitli araçlar kullanılabilir. Ancak bu çalışmada Android Studio tercih edilmiştir. Android Studio’da yeni bir flutter projesi oluşturulmalıdır. Proje oluşturulduktan sonra Terminalden aşağıdaki kod yazılarak firebase_core kütüphanesi projeye eklenmelidir.
flutter pub add firebase_core
Bu kod çalıştırıldıktan sonra pubspec.yaml dosyası içine “firebase_core: ^1.13.1” satırının eklendiği görülecektir. Versiyon numarası güncel sürüme göre değişiklik gösterebilir. Sonrasında ise flutter pub get yapılacak projedeki bağımlılıklar güncellenmelidir. Bir sonraki aşamada ise FlutterFire yazılımı kullanılmıştır. Bu yazılım, oluşturulan Firebase projesi ile oluşturulan flutter projesini ilişkilendirmek için kullanılmaktadır. Bu ilişkilendirme işlemi manuel olarak yapılabilmektedir. Ancak FlutterFire bu süreci oldukça basitleştirmektedir. FlutterFire yazılımı daha önce kurulmamışsa sisteme kurulması gerekmektedir. Bunun için Terminal sayfasında sırayla aşağıdaki komutlar çalıştırılmalıdır.
Giriş Sayfasını Oluşturma
Firebase veritabanı ve kullanıcı girişi sistemlerini kullanabilmek için aşağıdaki komutlar çalıştırılmalıdır. Bu komutlar çalıştırıldıktan sonra pubspec.yaml dosyasına ilgili satırlar otomatik olarak eklenecektir.
flutter pub add cloud_firestore flutter pub add firebase_auth flutter pub get
Giriş sayfası ayrı bir dosyada StatefulWidget sınıfı miras alınan Giris isminde bir sınıf ile oluşturulmuştur. Projede her bir sayfa ayrı dosyalar içinde oluşturulmuş olan StatelessWidget veya StatefulWidget sınıfları miras alınarak oluşturulmuştur. Ayrı dosyalarda barındırılmasının sebebi ise yazılan kodların karmaşıklığının azaltılarak bir dosyadaki yazılan satır sayısını düşük seviyelerde tutma ihtiyacıdır. Ayrı dosyalarda oluşturulan bu sınıflar kullanılmak istendiğinde import edilerek rahatlıklar kullanılabilmektedir. Giriş sayfasında kullanılan bazı widget’lar diğer sayfalarda da kullanılacağı için StatelessWidget sınıfı miras alınarak AuthButton, CustomFormField, CustomHeader, CustomRichText gibi yeni sınıflar oluşturulmuş ve bu sayfalarda kullanılmıştır. Örneğin CustomFormField sınıfı aşağıdaki gibi tanımlanmıştır.
Bu tür widgetlar sayesinde ekranda benzer görüntüyü elde etmek için çok daha az kod yazmak yeterli olmaktadır. Projedeki tüm metin kutuları CustomFormField olarak tasarlanmıştır. Eğer bu şekilde bir widget tanımı yapılmamış olsaydı her metin kutusu kullanılması gereken yerde yaklaşık 60 satır kod yazmak gerekecektir.
CustomFormField sınıfı incelendiğinde çeşitli parametrelerin kullanıldığı görülmektedir. Bu parametreler sayesinde bu sınıf farklı ihtiyaçlara uyum sağlayabilecek
bir esneklik kazanmış olmaktadır. Örneğin obsecureText parametresi true olarak ayarlanarak metin kutusunun şifre girişine uygun hale gelmesi sağlanabilmektedir. Şifre girişi metin kutularında karakterler * veya farklı bir karakter ile gizlenmektedir. Ayrıca sık kullanılan kodları widget olarak ayrı dosyalarda saklamak daha önce bahsedildiği gibi yazılan programın karmaşıklığını azaltmak açısından da önem arz etmektedir. Giriş sayfası ilk açıldığında aşağıdaki kod ile kullanıcının daha önce giriş yapıp yapmadığı kontrol edilmektedir.
@override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { if (FirebaseAuth.instance.currentUser != null) { Navigator.push( context, MaterialPageRoute( builder: (context) => Defter(), ), ); } }); }
Burada kodlar, StatefulWidget sınıfından türetilen Giris sınıfı için initState fonksiyonunu içine yazılmıştır. initState fonsksiyonu StatefulWidget sınıfından miras alınmakta override edilmektedir. Bu fonksiyon, StatefulWidget nesnesi ağaca eklendiğinde bir kez çağrılır. Böylece bu kodlar Giris sınıfı çağrıldığında anda çalışmış olacaktır. super.initState() ile miras alınan StatefulWidget sınıfının ilgili fonksiyonunun çalıştırılması sağlanmıştır. WidgetsBinding.instance.addPostFrameCallback olayı ile Giriş sayfası ekranda oluşturulduktan sonra tetiklenecek yeni bir olay tanımlanmaktadır. Bu olay sayesinde Giris sınıfının widgetları ekranda oluşturulduktan sonra bu olay ile belirtilen fonksiyon çalıştırılmaktadır. Bu örnekte ise addPostFrameCallback fonksiyonuna parametre olarak yazılan isimsiz fonksiyon tanımlaması yapılmıştır.
Dolayısıyla sayfa ekranda oluştuğu anda bu isimsiz fonksiyon çalıştırılır. Bu isimsiz fonksiyonda ise FirebaseAuth.instance.currentUser değerinin null olup olmadığı kontrol edilmektedir. Eğer null değil ise daha önce kullanıcı girişi yapıldığı anlamına gelecektir. Bu durumda tekrar kullanıcı girişi yaptırmamak için Navigator.push ile sistem Defter sayfasını açmaktadır. Giriş sayfasında kullanıcı adı ve şifre girdikten sonra Giriş düğmesine tıklandığında ise aşağıdaki tıkla fonksiyonu çalışmaktadır.
Tıkla fonksiyonu Future türünde ve async olarak tanımlanmıştır. Bunun sebebi await ifadesinin sadece async olarak tanımlanan fonksiyonlarda çalışabilmesidir. Bir fonksiyonun async olabilmesi için geri dönüş türünün Future olması gerekmektedir. T fonksiyonun asıl geri döndüreceği türdür. Bu örnekte geriye döndürülmesi gereken bir değer olmadığı için T yerine void yazılmıştır. Async olarak tanımlanan fonksiyonlar çağrıldığında ayrı bir thread (paralel bir süreç) olarak çağrılmaktadır. Özellikle zaman alacak süreçlerde bu yöntem tercih edilmektedir. Örneğin internette indirme yapılmasını gerektiren bir işlem gerçekleştirilecek ise async fonksiyonlardan yararlanılmalıdır. Böylece kullanıcılar indirme işlemi devam ederken dahi uygulama ile etkileşim kurmaya devam edebileceklerdir. İnternetten indirme yapılması gereken bir süreçte async kullanılmamış olsaydı, uygulama indirme süresi boyunca donacak ve tepki
vermeyecekti. Özellikle internetin yavaş olduğu senaryolarda bu donma süresi çok uzayabilir. Kullanıcı uygulamanın kilitlendiğini düşünüp, uygulamayı sonlandırma yoluna gidebilir. Bu gibi durumlarla karşılaşmamak için async fonksiyonlardan yararlanılmalıdır. signInWithEmailAndPassword fonksiyonu da bir async fonksiyondur. Ancak burada await ifadesi ile bu fonksiyonun sonucunun beklenmesi sağlanmıştır. Eğer bu yapılmamış olsaydı signInWithEmailAndPassword fonksiyonu ayrı bir thread olarak çalışacak ve fonksiyonun sonucu beklenmeden if satırı ile giriş yapılıp yapılmadığı kontrol edilecektir. signInWithEmailAndPassword işleminin internete bağlı olarakuzun süreceği düşünülürse altında bulunan if satırının her zaman false sonucunu döndüreceği varsayılabilir. Buradaki await ifadesi ile signInWithEmailAndPassword işlemi tamamlanana kadar burada beklenilmesi sağlanmıştır. Böylece if ifadesi doğru bir karşılaştırma yapabilmektedir. tıkla fonksiyonu ise Giriş düğmesine basıldığında çağrılmaktadır. Burada da bir async süreç olduğu için programın donma durumu söz konusu olmamaktadır. Özetle tikla fonksiyonunda FirebaseAuth bileşeni kullanılarak kullanıcının girdiği eposta adresi ve şifre ile kullanıcı girişi yapılmaya çalışılmaktadır. Eğer giriş başarılı olursa sistem Defter sayfasına yönlendirmektedir. Eğer giriş başarılı olmaz ise üretilen hata koduna göre “Kullanıcı bulunamadı” veya “Şifre Yanlış” uyarıları ScaffoldMessenger ile ekranın en altına gösterilmektedir.
Kayıt Ol Sayfasını Oluşturma
Kullanıcı Giris sayfasında Kayıt Ol linkine tıklandığında Görsel 8.6’te görülen ekran açılmaktadır. Bu sayfada yeni bir kullanıcı e-Posta adresini ve şifresini yazarak sisteme kaydolabilmektedir. Kullanıcıdan şifresini iki defa yazması istenmektedir. Böylece hatalı şifre yazımının önüne geçilmeye çalışılmıştır.
Kayıt ol sayfasında kullanıcı e-Posta adresini ve şifresini belirleyerek sisteme kayıt olabilmektedir. Kayıt ol düğmesine tıklandığı anda aşağıda kodlarda verilen tiklaKayit fonksiyonu çalışmaktadır. Fonksiyon içinde await ifadesi kullanıldığı için tiklaKayit fonksiyonu async olarak tanımlanmıştır.
Defter Sayfasını Oluşturma
Defter sayfasında bir ListView ile kullanıcının daha önce kaydetmiş olduğu kişilerin listesi yer almaktadır. Defter sayfasında kişilerin veritabanından okunarak listelenmesi getir fonksiyonu ile sağlanmaktadır.
Yeni Kayıt Sayfasını Oluşturma
Defter sayfasında yeni kayıt eklenmek istendiğinde sayfanın sağ al bölümünde yer alan + simgesine tıklanmalıdır. Bu simgeye tıklandığında Yeni Kayıt sayfası açılır. Yeni kayıt sayfasında ad soyad, telefon numarası ve e-Posta adresi bilgileri girilerek yeni kişi kaydı yapılabilmektedir. Kaydet düğmesine tıklandığında aşağıda kodları verilen ekle fonksiyonu çalışmaktadır. Ekle
fonksiyonu da içinde await olması bakımından async olarak tanımlanmıştır.
Kayıt Düzenle Sayfasını Oluşturma
Kayıt düzenle sayfasının ekran görüntüsü Görsel 8.10’de verilmiştir. Kayıt düzenle sayfasında, kayıt düzenleme, kayıt silme ve kişinin telefon numarasını arama işlemleri yapılabilmektedir. Bu işlemlerin yapılabilmesi için formun altın 3 adet düğme yerleştirilmiştir.
İlk olarak kişiye ait telefon numarasını arama işlemi açıklanmıştır. Aslında burada uygulanan işlem uygulama içinden doğrudan telefon etme durumu değildir. Onun yerine cep telefonunun Telefon uygulamasını açmak ve aranacak telefon numarası bölümüne ilgili kişinin telefon numarasının gelmesini sağlamaktır. Bunun sonucunda kullanıcının Telefon uygulamasından sadece Ara düğmesine basması yeterli olacaktır. Telefon ile istenilen telefon numarasını arayabilmek için url_launcher eklentisine ihtiyaç bulunmaktadır. Bu eklenti “flutter pub get url_launcher” komutu ile projeye eklenebilir. Komut çalıştıktan sonra pubspec.yaml dosyasında dependencies bölümüne ilgili satır eklenmektedir. Sonrasında ise gerekli import satırları yazıldıktan sonra Ara düğmesi ile ilişkilendirilen aşağıdaki fonksiyonu çalıştırmak yeterli olmaktadır.
Silme işlemi de doc(widget.kisi.kod).delete() fonksiyonu ile gerçekleştirilmektedir. Benzer şekilde widget.kisi.kod değerinden yararlanılmıştır. Bu kod çalıştıktan sonra silme işlemi gerçekleştirilerek kullanıcı tekrar Defter sayfasına yönlendirilmektedir.