Capacitor İle Angular Uygulamalarını Mobil Uygulamalara Dönüştürme
Merhaba,
Bu içeriğimizde Ionic ekibi tarafından geliştirilmiş olan ve Angular, React, Vue.js vs. gibi web uygulamalarının mobil platformlarda çalıştırılabilmesini sağlayan bir köprü(bridge) ve runtime çözümü olan Capacitor teknolojisini inceliyor olacağız.
Capacitor Nedir?
Capacitor; Angular ve React gibi web tabanlı uygulamaları platforma özgü(native) özelliklere erişebilen mobil uygulamalara dönüştürmemizi kolaylaştıran ve kamera, konum vs. gibi ilgili cihazın yerel özelliklerinden kolayca erişim sunarak istifade etmemizi sağlayan ve bunun yanında TypeScript desteği ve esnek eklenti sistemi sayesinde biz geliştiricilere basit ve hızlı deneyimler sağlayan bir kütüphanedir.
Capacitor sayesinde aynı kod tabanını kullanarak modern web uygulamalarınızın iOS ve Android sürümlerini zahmetsizce yayınlayabilir ve böylece platformlar arası çalışma(cross-platform) ihtiyacını rahatlıkla karşılayabilirsiniz. Tabi bunu yaparkende bir yandan geliştirme aşamasında olan uygulamalarınızın iOS ve Android sürümlerinin takibini canlı yeniden yükleme(live reload) özelliği sayesinde hızlıca gerçekleştirebilirsiniz.
Normal şartlarda bir Angular ya da React uygulaması, yalnızca tarayıcı API’leriyle sınırlı kapsama sahipken, Capacitor sayesinde kamera, dosya sistemi, bildirimler vs. gibi cihaza/platforma özgü API’leri de kullanılabilmesine imkan tanımakta ve böylece uygulamanın gerçek bir mobil uygulama gibi çalışabilmesini sağlamaktadır.
Kısaca Capacitor; geliştirilen modern web uygulamalarının gerçek bir mobil uygulamasına dönüştürülmesini ve bunu yaparkende mobil cihazların özelliklerinden etkin bir şekilde istifade edilmesini sağlayan bir kütüphanedir.
Capacitor Nasıl Kullanılır?
Bir Angular uygulamasında Capacitor’ü kullanabilmek için öncelikle kurulumunun gerçekleştirilmesi gerekmektedir. Bunun için npm i @capacitor/core
ve npm i -D @capacitor/cli
dependency’lerinin yüklenmesi ve ardından npx cap init
talimatı eşliğinde Capasitor’ün başlatılması gerekmektedir. Tabi bu sonuncu işlemi gerçekleştirirken cli tarafından aşağıdaki görselde olduğu gibi birkaç soruyla karşılaşılacaktır;Görüldüğü üzere Name ve Package ID bilgileri istenilmektedir. Name, uygulamanın görünür adı olarak düşünülebilir. Misal olarak uygulamanızı Google Play yahut App Store gibi bir mağazada yayınlayacaksanız kullanıcıların göreceği isme karşılık gelmektedir. Package ID ise uygulamanın Android ve iOS platformlarında eşsiz bir şekilde tanımlanması için kullanılan bir kimliktir. Burada dikkat edilmesi gereken nokta; Package ID değerinin genellikle Java paket ismine benzer bir formatta yani ters domain adı formatında yazılıyor olmasıdır. (bknz:
com.şirketadi.projeadi
gibi…) Velhasıl bizlerin uygun bir şekilde bu değerleri vermemiz gerekmektedir.
Eğer ki Capasitor ayağa kaldırıldıysa uygulamanın ana dizininde içeriği aşağıdaki gibi olan capacitor.config.ts isminde bir temel yapılandırma dosyası oluşturulacaktır.
import type { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'com.ngsoft.capacitorexample', appName: 'capacitor-example', webDir: 'dist' }; export default config;
Görüldüğü üzere dosyanın içerisinde biraz önce girilen bilgiler tutulmakta ve bir yandan da platform bağımlılıkları tanımlanmaktadır.
Evet, bu aşamadan sonra artık uygulamanın Android ve iOS sürümlerini oluşturabiliriz. Bunun için öncelikle npm i @capacitor/android @capacitor/ios
talimatı eşliğinde ilgili platformların yüklenmesi gerekmektedir. Platformlar yüklenip, dependency’leri package.json dosyasına eklendikten sonra uygulamanın Android ve iOS projelerini oluşturmak için npx cap add android
ve npx cap add ios
talimatlarının çalıştırılması gerekmektedir. Tabi bu talimatları çalıştırmadan önce uygulamanın ng build --configuration production
talimatı eşliğinde derlenmesi gerekmektedir. Çünkü Capacitor, uygulamanın derlenmiş halini kullanmaktadır.Derleme neticesinde uygulamanın ana dizininde
dist/
klasörü içerisinde çıktının hali hazırda sunulduğunu göreceksiniz. Burada yukarıdaki görselden de dikkat ederseniz uygulamanın çıktısı dist\capacitor-example\browser
dizinine atılmaktadır. Ee haliyle biraz önce oluşturduğumuz capacitor.config.ts dosyasındaki webDir
alanını buna göre güncellememiz gerekmektedir ki uygulamanın Android sürümü de doğru kaynaktan beslenebilsin…
import type { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'com.ngsoft.capacitorexample', appName: 'capacitor-example', webDir: 'dist/capacitor-example/browser' }; export default config;
Evet, artık uygulamanın Android ve iOS projelerinin oluşturulması için yukarıda bahsi geçen gerekli talimatı verebiliriz;Bu talimatlar neticesinde uygulamanın root dizininde
ios/
ve android/
klasörlerinin oluşturulduğu görülecektir.
iOS platformu için macOS bir cihaza ve Xcode’a ihtiyaç olduğunu unutmayınız! Android platform için ise Windows, macOS yahut Linux işletim sistemlerinde gönül rahatlığıyla çalışabilir, Android Studio IDE’si eşliğinde de geliştirmelerinizi takip edebilirsiniz.
Bizler malumunuz Windows ortamında çalışma sergilediğimiz için ee haliyle Android sürümü üzerine odaklı bir şekilde içeriğimize devam ediyor olacağız. Şimdi, yaptığımız bunca çalışma neticesinde uygulamanın Android sürümünü ayağa kaldırmaya çalışalım. Bu yüzden npx cap open android
talimatı eşliğinde uygulamanın Android sürümünü Android Studio IDE’sinde açalım.Yukarıdaki ekran alıntısından görüldüğü üzere uygulamamızın Android sürümü başarıyla ayağa kaldırılmış vaziyettedir.
Uygulama Kodunun Mobil Projeyle Senkronize Edilmesi
Uygulamanın mobil versiyonunu oluşturduktan sonra uygulamada meydana gelen yeniliklerin mobil versiyona anlık olarak yansıtılması isteniyorsa eğer işte burada uygulama kodu ile mobil versiyon arasında bir senkronizasyon işlemi yapılması gerekmektedir. Bunun için uygulamada değişiklikler yapıldıktan sonra önce ng build
ile derlenmesi ve ardından npx cap sync
talimatının verilmesi yeterli olacaktır. Bu talimat hem Android hem de iOS platformlar için tüm değişiklikleri senkronize edecektir. Ha yine de sizler tek bir platform üzerinden senkronizasyon hedefliyorsanız bunun için de npx cap sync ios
– npx cap open ios
şeklinde talimatlarınızı platforma göre özelleştirebilirsiniz. Velhasıl, yapılan bu senkronizasyon işlemi neticesinde uygulamanın capacitor.config.ts dosyasında belirtilen webDir
alanındaki dizinde oluşturulan yenilikler mobil versiyonun ilgili dosyalarına aktarılacak ve varsa ekstradan dependency’ler de yüklenecektir.
Özellikle her major değişiklik sonrasında
npx cap sync
talimatının kullanılması gerektiğini unutmayınız.
Canlı Yeniden Yükleme (Live Reload)
İyi de hoca, Angular’da nasıl ki ng serve
ile anlık değişiklikleri tarayıcıya yansıtabiliyoruz, bunu mobil versiyonlar da da yapamıyor muyuz? diye uzun karışık bir soru aklınızda canlanmış olabilir… El-cevap, elbette ki yapabiliyoruz. Hatırlarsanız içeriğimizin ilk satırlarında bahsettiğimiz gibi Capacitor canlı yeniden yükleme(live reload) özelliğine sahiptir. Bu özellikten istifade edebilmek için uygulamanın IPv4 adresinden ayağa kaldırılması gerekmektedir. Bunun için de ng serve --host 0.0.0.0
şeklinde talimatın verilmesi gerekmektedir.Bu talimat neticesinde uygulama yukarıdaki görselden de anlaşılacağı üzere IPv4 adresi üzerinden de host edilecektir. Bu yaptığımızın konuyla ne alakası var la hoca? diye sorduğunuzu duyar gibiyim… Normal şartlarda,
ng serve
talimatı localhost
üzerinden yani sadece geliştirme yapılan bilgisayar üzerinden erişilebilecek şekilde uygulamayı ayağa kaldıracaktır. Ancak telefon ya da tablet gibi fiziksel bir cihaz üzerinden uygulama test etmek isteniyorsa bu taktirde uygulamanın ilgili cihaz tarafından erişilebilir olması gerekmektedir. İşte tamda bu noktada uygulamanın tüm ağ arayüzlerinden gelen istekleri dinlemesini sağlayacak olan --host 0.0.0.0
parametresi kullanılır.
Uygulamayı belirtilen şekilde serve ettikten sonra capacitor.config.ts dosyasında aşağıdaki gibi IPv4 adresinin bildirilmesi gerekmektedir;
import type { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'com.ngsoft.capacitorexample', appName: 'capacitor-example', webDir: 'dist/capacitor-example/browser', server: { url: "http://192.168.0.26:4200/", cleartext: true } }; export default config;
Bu yapılandırmayı gerçekleştirdikten sonra da npx cap sync
talimatıyla senkronizasyonun sağlanıp, bu yeniliğin mobil versiyonlara da aktarılması sağlanmalıdır. Vee böylece artık uygulamada yaptığımız herhangi bir değişikliğin anlık olarak mobil versiyonlara da yansıdığını gözlemleyebiliriz.
Live reload özelliği yalnızca geliştirme sırasında kullanılması gereken bir araç olduğundan dolayı mobil uygulamayı yayınlarken kapatılması gerekmektedir.
Cihaz Kamerasına, Konum Bilgisine vs. Erişim
Capacitor ile mobil cihazın birçok özelliğine erişim gösterilip, kullanılabilmektedir. Bizler burada kamera ve konum bilgisi üzerinden örneklendirme yapacağız. Eğer ki daha fazla mobil özelliğe erişim ihtiyacı söz konusuysa Capacitor’ün resmi dokümantasyonu üzerinden (bknz: official plugins) gerekli incelemelerde bulunabilirsiniz.
- Kamera Erişimi
Angular uygulaması üzerinden Capacitor aracılığıyla kameraya erişim gösterebilmek için öncelikle
npm install @capacitor/camera
paketinin uygulamaya yüklenmesi gerekmektedir. Ardından kamera erişimine dair kullanıcı tarafından telefon aracılığıyla gerekli izinlerin verilebilmesi için aşağıdaki yapılandırmalarınAndroidManifest.xml
dosyasına eklenmesi gerekmektedir.<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Bu izinler anlaşılacağı üzere fotoğraf dosyalarını okumak ve kaydedebilmek için storage ile ilgili izinlerdir.
İzin işlemlerini tamamladıktan sonra artık kamerayla ilgili çalışmalara gelebiliriz. Bunun için aşağıdaki gibi bir çalışma yapılabilir;
. . . <p> <button (click)="fotografCek()">Fotoğraf Çek</button> <br> <img style="width: 343px; height: 330px;" [src]="photo()"> </p> . . .
. . . photo = signal<string | undefined>(""); async fotografCek() { const image = await Camera.getPhoto({ quality: 90, allowEditing: false, resultType: CameraResultType.Base64 }); this.photo.set(`data:image/jpeg;base64,${image.base64String}`); } . . .
Yapılan tüm bu çalışmalardan sonra
npx cap sync
talimatıyla uygulama senkronize edilmelidir. Ardından Android Studio üzerinden yapılan çalışmaları test edebiliriz;Yukarıdaki ekran alıntısından da görüldüğü üzere Android Studio üzerinden kamerayı test ederken bir kamera simülasyonu üzerinden test gerçekleştirilebilmektedir. Uygulamayı yayınlayıp, telefon üzerinden çalışma sergilediğimizde ise gerçek kameranın kullanıldığını göreceğiz.
Şimdi yaptığımız bu çalışma uygulamanın hem web hem de mobil versiyonlarında varlık göstermektedir. Halbuki kamerayla ilgili bu çalışmaları bizler sadece mobil versiyonunda kullanmak isteyeceğiz. İşte böyle bir durumda tek yapılması gereken aşağıdaki gibi küçük bir css dokunuşudur.
. . . <p class="mobil-goster"> <button (click)="fotografCek()">Fotoğraf Çek</button> <br> <img style="width: 343px; height: 330px;" [src]="photo()"> </p> . . .
.mobil-goster { display: none; } @media(max-width:760px) { .mobil-goster { display: block; } }
Bakın, görüldüğü üzere mobil versiyona geçildiği taktirde kamera işlevleri devreye girmektedir.
- Konum Erişimi
Telefonun konum erişimi için isenpm install @capacitor/geolocation
paketinden istifade edilecektir. Paketi yükledikten sonraAndroidManifest.xml
dosyasında aşağıdaki izinlerin yapılandırılması gerekmektedir.<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.location.gps" />
Bu işlemden sonra mevcut konumla ilgili bilgiler aşağıdaki gibi çekilebilir;
async mevcutKonum() { const position = await Geolocation.getCurrentPosition(); alert(`Enlem : ${position.coords.latitude}\nBoylam : ${position.coords.longitude}`) }
Ionic Component’lerinden İstifade Etme
Ionic; HTML, CSS ve JavaScript gibi web teknolojilerini kullanarak mobil uygulama geliştirme deneyimini kolaylaştıran bir framework’dür. Ve bizler, Angular uygulamalarında Ionic component’lerini kullanarak mobil cihazlara has tasarlanmış olan araçlardan istifade edebilmekte ve böylece kullanıcı deneyimi açısından daha elverişli çalışmalar gerçekleştirebilmekteyiz.
Bunun için öncelikle npm install @ionic/angular
talimatı eşliğinde Ionic’in uygulamaya yüklenmesi gerekmektedir. Ardından istenilen component’e dair HTML ve TypeScript geliştirmesi gerçekleştirildikten sonra uygulamayı derleyip, senkronize edebilirsiniz.
Misal olarak aşağıda ion-select
component’inin çalışmasını inceleyebilirsiniz;
<label>Ionic</label> <ion-list> <ion-item> <ion-select label="Default label" placeholder="Favorite Fruit"> <ion-select-option value="apple">Apple</ion-select-option> <ion-select-option value="banana">Banana</ion-select-option> <ion-select-option value="orange">Orange</ion-select-option> </ion-select> </ion-item> <ion-item> <ion-select label="Fixed label" label-placement="fixed" placeholder="Favorite fruit"> <ion-select-option value="apple">Apple</ion-select-option> <ion-select-option value="banana">Banana</ion-select-option> <ion-select-option value="orange">Orange</ion-select-option> </ion-select> </ion-item> <ion-item> <ion-select label="Stacked label" label-placement="stacked"> <ion-select-option value="apple">Apple</ion-select-option> <ion-select-option value="banana">Banana</ion-select-option> <ion-select-option value="orange">Orange</ion-select-option> </ion-select> </ion-item> <ion-item> <ion-select label="Floating label" label-placement="floating"> <ion-select-option value="apple">Apple</ion-select-option> <ion-select-option value="banana">Banana</ion-select-option> <ion-select-option value="orange">Orange</ion-select-option> </ion-select> </ion-item> </ion-list>
. . . import { IonItem, IonList, IonSelect, IonSelectOption } from '@ionic/angular/standalone'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet, IonItem, IonList, IonSelect, IonSelectOption], templateUrl: './app.component.html', styleUrl: './app.component.scss' }) export class AppComponent { . . . }
@import '@ionic/angular/css/ionic.bundle.css';
Nihai olarak;
Böylece Angular mimarisiyle geliştirilen uygulamaların oldukça düşük maliyetler eşliğinde, rahatlıkla ve daha da önemlisi hızlıca Android ve iOS sürümlerini çıkarabilir ve en kısa zamanda mağazalarda yayında bulunarak, ticari faaliyetlerinizde mobil kitleyi de hesaba katabilirsiniz.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
Not : Örnek çalışmaya aşağıdaki github adresinden erişebilirsiniz.
https://github.com/gncyyldz/CapacitorExample