WebView
webview kütüphanesine giriş yapmadan önce bahsetmek istediğim birkaç konu var. Daha önce aramızda electron.js‘i duyanlar olmuştur. Hani şu Visual Studio Code, Skype, Atom, Discord ve Slack gibi başarılı uygulamaların yazılmış olduğu Javascript kütüphanesinden bahsediyorum. Electron.js ile yazılan uygulamalar HTML, CSS ve Javascript‘in gücüyle kaliteli bir grafiksel kullanıcı arayüzüne ulaşabiliyor. Eğer bir Web Developer’sanız kolayca masaüstü uygulaması yazabiliyorsunuz. Ama Electron.js ile yazılmış uygulamaların kötü yanları da var tabi. Uygulama boyutu bunlardan en sıkıntılı olanı. En basit bir uygulamanın boyutu 150 Megabyte olabiliyor. Bir de electron-packager yardımı ile uygulama build edilirken uzun süre bekliyorsunuz. Şimdi gelelim bizi bu olaylardan kurtaracak olan gözümün nuru Golang Kütüphanesi olan webview kütüphanesine ♥
webview kütüphanesi zserge arkadaşımız tarafından yazılmış olan, web sayfaları tasarlayıp programa dönüştürebildiğimiz, backend kısmını Golang rahatlığında yazdığımız bir kütüphane (veya paket)dir.
zserge/webview repo'su webview/webview'a taşınmıştır.
Build işlemi sonrası aslında elimizde bir internet tarayıcısı olmuş oluyor. Bu tarayıcı üzerinden hazırlamış olduğumuz web sayfası görüntüleniyor. Frontend ve Backend arasındaki iletişimi ise Bind ile sağlıyoruz. Bu özelliği birazdan kodlar içerisinde açıklayacağım.
Sadece Windows, GNU/Linux ve macOS için uygulama geliştirebiliyoruz. GNU/Linux üzerinde gtk-webkit2, macOS üzerinde Cocoa/Webkit ve Windows üzerinde Edge alt yapısını kullanıyor. Linux üzerinde çalışması için, gtk-webkit2 paketini yüklemeyi unutmayın. Bu detaylara bakacak olursak, Windows üzerinde çalışırken Edge Browser’ı kullanacak. macOS ve GNU/Linux üzerinde ise Chrome benzeri bir altyapı kullanacak. Bu durumda GNU/Linux ve macOS için geliştirmek daha mantıklı çünkü daha fazla görsel efekt imkanı var olacaktır. Örnek: CSS3’teki -webkit- etiketi… Gelelim kütüphanenin kurulumuna. Aşağıdaki komut ile kütüphanemizi indiriyoruz.
go get github.com/webview/webview
Kütüphanemizi kurduğumuza göre ufak bir örnek görelim. Daha sonra detaylı örnekler göstereceğim.
Yukarıdaki gibi basit bir yöntem ile bir gui program oluşturabiliyorsunuz. Seviyeyi biraz yükseltelim ve sonraki örneğimize geçelim.
Hemen açıklamasını yapayım. Kendi sunucumuzu oluşturmak için “net/http” kütüphanesini ekledik. serverOlustur() fonksiyonunda klasik web server oluşturmak için gerekli kodları yazdık. Görüntülenecek içeriği handler() fonksiyonunda belirttik. main() fonksiyonu içerisindeki kodlarımıza geçelim. serverOlustur() fonksiyonunu Goroutine ile yazmazsak web server ayağa kaldırıldığında (açıldığında) kapanana kadar alt taraftaki webview kodlarının çalışmasına sıra gelmez. Başına go ekleyerek aynı anda server’ın oluşturulmasına ve diğer kodların çalışmasını sağlıyoruz. webview kodlarımızda ise oluşturduğumuz web server’ın bilgilerini ve pencere ayarlarını giriyoruz. Biraz değişiklikler ile istediğimiz bir klasörü göstermeye ayarlayabiliriz.
Projemizin yapısı aşağıdaki gibi olsun.
index.html dosyamız aşağıdaki gibi olsun.
main.go dosyamız ise aşağıdaki gibi olsun.
Sıra geldi Backend (Golang) ve Frontend (Javascript) arasındaki iletişimi sağlamaya. Aşağıdaki işlemleri yukarıdaki klasör yapısında göre yapacağız. Yani bu şekilde:
Frontend’den Backend’e Veri Gönderme (JavaScript ===> Go)
Bu işlemi gerçekleştirebilmemiz için webview tarayıcısının frontend’deki sinyalleri dinlemesi gerekir. Golang tarafından dinlemek için Bind() fonksiyonunu kullanıyoruz.
Örnek bir main.go dosyası oluşturalım.
Bind()
fonksiyonunu pencere.Run()
'dan önce yazmalıyız. Eğer sonra yazarsak, çalışma zamanı Run()
fonksiyonu kapatılmadan Bind()
fonksiyonuna gelmeyeceği için yazmamızın bir mantığı olmaz.
Sıra geldi websayfamızdaki kodları yazmaya.
klasor klasörümüzün içerisine uygulama.js dosyası oluşturalım.
index.html dosyamıza ise bir yazı kutusu ve buton ekleyelim.
Ek olarak da uygulama.js dosyamızı html etiketi olarak ekleyelim.
Oluşturduğumuz HTML elementlerine id'ler vererek, bunları Javascript'te kullanacağız.
uygulama.js dosyamızun içeriği ise aşağıdaki gibi olsun.
Bu işlemler sonucunda uygulamamızı projemizin ana dizinindeyken go run .
şeklinde başlatalım.
Yazı kutusuna isim girip Gönder butonuna baştığımızda konsol tarafında merhaba isim
şeklinde bir çıktı görürüz.
Backend’den Frontend’e Veri Gönderme (Go ===> JavaScript)
Aslında burada yapacağımız olay bir JavaScript kodu çalıştırmak veya tetiklemek de denebilir. Tıpkı Developer Console'dan yaptığımız gibi..
Bu işlem için Eval()
fonksiyonundan faydalanıyoruz. Örnek için yukarıdaki kodlarımıza devam edelim.
merhaba
fonksiyonunu dinliyoruz demiştik. Bind()
içerisinde komut satırına isim bastırmak yerine JavaScript konsoluna ismi bastıralım.
Bind()
fonksiyonumuzun içeriği şöyle olsun.
Uygulamamızı çalıştırıp yazı kutusuna bir isim girdiğimizde Komut satırından şöyle bir çıktı alabiliriz:
http://localhost:5555/:1:12: CONSOLE LOG Merhaba, Kaan!
İsterseniz Webview içerisindeki Developer Tool ile de bakabiliriz.
Sayfaya sağ tıklayalım ve Inspect Element'e tıklayalım. Açılan bölümde Console sekmesine geçelim. All şeçeneğinin şeçili olduğundan emin olalım. Ve işte! log çıktımızın burada.
Bu işlemler ile kolay bir şekilde Backend-Frontend arası iletişimi sağlayabilirsiniz.
Golang ile Webview'a Asenkron Müdahale Etme
Go tarafında asenkron işlemler için Goroutine'leri kullandığımızı belirtmiştik. Backend tarafında zaman alan bir işlemi goroutine ile asenkron bir işlem parçacığı haline getirmezsek. İşlem tamamlanana kadar webview penceremiz yanıt vermez. Yani herhangi bir şeye tıklayamayız. Bu yüzden uzun sürecek arkaplan işlemlerini Webview'e aseknron şekilde çalıştırmamız gerekir.
Örnek bir Bind()
fonksiyonunda aseknron bir işlemi inceleyelim.
Yukarıdaki örnekte JavaScript tarafından çalıştırılacak merhaba fonksiyonunu dinliyoruz. Bu fonksiyon bize string tipinde bir değer iletiyor. Asenkron olarak anonim bir fonksiyon oluşturuyoruz ve içeriğinde 3 saniye beklemesini istiyoruz. Son olarak ekrana isim değişkenindeki değeri bastırıyoruz.
Eğer bu kodları asenkron olarak çalıştırmasaydık, Webview penceremiz 3 saniye boyunca yaptığımız hiçbir işleme tepki vermeyecekti.
Şimdi buraya kadar karışık bir olay yok aslında. Asıl asenkron mantığı 3 saniye bekleyip çıktımızı JavaScript konsoluna bastırmak olacaktır. Aralarındaki asenkron olayı bu şekilde sağlancaktır.
Normalde asenkron iki işlemin birinden diğerine ait olan bir işlemi yapmak için işaretçileri (pointer) kullanabiliriz. Fakat Webview nesnesine bir işaretçi atayamayız. Çünkü webview ile oluşturulan nesnemiz bir interface'tir.
Örnek bir deneme girişimi 😀
Şuana kadar gösterdiğim şeyler bir yanlış yapmayın diyeydi. Yukarıdaki yöntemi doğru değildir. Doğrusu Dispatch()
fonksiyonunu kullanmaktır. Go kodlarımızın tamamını görecek şekilde bir örnek verelim. Örnek kullanımı:
Webview Kütüphanesindeki Diğer Fonksiyonlar
Destroy()
Webview penceremizi sonlandırır.
Terminate()
Pencerenin çalışmasını keser.
Eval()
Pencerede JavaScript kodu çalıştırmamızı sağlar.
Init()
Pencereye JavaScript kodu iliştirir. Eval()
fonksiyonundan farkı ise sayfa değişse bile JavaScript kodu sayfada kalır. Eval()
ile bir kere mahsus JavaScript kodu çalıştırılır. Init()
fonksiyonunda sayfa yenilenince bile kod çalışırır.
Navigate()
Webview penceresinin belirtilen adresi yüklemesini sağlar.
Run()
Pencereyi başlatır.
SetSize()
Pencerenin boyutunu ve etkileşimini ayarlar.
SetTitle()
Pencerenin başlığını değiştirmemizi sağlar.
Last updated