DevNot 2019 Summit .Net Core, Ionic 4 Mobile Workshop
Selamlar,
13 Nisan Cumartesi günü, İstanbul Nişantaşı Üniversitesinde DevNot Summit etkinliğinde, Cross Platform Mobil bir workshop gerçekleştirdik. Amaç, hem android de hem IOS’da çalışan mobile bir oyun programlama idi. Bu amaç ile, MacOs ortamında başta IOS olmak üzere cross platform çalışacak şekilde uygulamamızı geliştirdik. Kodları canlı canlı yazıp, hataları beraberce düzelttik. Hatta, bazı yolları sizin isteğinize göre tekrardan şekillendirdik.
Konu: Yeni bir web sayfası açıldığında, karşımıza bir QRBarcode gelecektir. Mobile uygulamadan, bu QRBarcode taranacak ve 2 platform birbiri ile Socket yardımı ile konuşacaktır. Teknoloji .Net Core 2.0 SignalR Hub Socket olacaktır. Bu işlemden sonra karşımıza, mobile uygulamada komut verilebilecek buttonlar ve Web Sayfasında ise QRBarcode kaybolup, üzerinde , işlem yapılacak araba resmi gelecektir. Mobil uygulama, Ionic 4.0 Cordova dır. Daha sonrasında, arabaya mobileden komutlar gönderilip, kapıların açılması ve farların yakılması sağlanacaktır.
QRBarcode, Connect olan Client’ın connectionID’sini üzerinde barındırır. Bu şekilde mobile uygulama nereye komut göndereceğini bilebilmektedir. Bu “id” değeri, signalR Hub Connection sınıfının herbir client için atadığı connectionID değeridir. Aşağıdaki örnekte, web tarafındaki client’ın connectionID’si ve oluşacak resmin adı parametre olarak alınmıştır. Daha sonra “Google Chart Servisi” kullanılarak, ilgili barcode, binary stream olarak alınır ve “wwwroot/images” altına kaydedilir. .Net Core altında file dosyaları, wwwroot altına konması gerekmektedir. Ayrıca dışarıdan erişime de açılması gerekmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public string CreateBarcode(string connectionId, Guid imageName) { string Code = connectionId; string width = "200"; string height = "200"; var url = string.Format($"http://chart.apis.google.com/chart?cht=qr&chs={width}x{height}&chl={Code}"); WebRequest request = WebRequest.Create(url); WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); using (FileStream fileStream = new FileStream("wwwroot/images/" + imageName.ToString() + ".png", FileMode.Create)) { byte[] bytesInStream = new byte[10000]; stream.Read(bytesInStream, 0, bytesInStream.Length); stream.Close(); fileStream.Write(bytesInStream, 0, bytesInStream.Length); fileStream.Flush(); fileStream.Close(); } return servicePath + ":1923/images/" + imageName + ".png"; } |
Client connectionID: yvz5eLBSBtx7c4eETn-qVA
SignalR Socket işlemleri için, “Car: Hub” sınıfı oluşturulmuştur. Aşağıda görüldüğü gibi, web tarafında connect olan client’ın connectionID’si, “web” ve “mobile” platform’a göre ayrı ayrı çekilmiştir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public override async Task OnConnectedAsync() { string FromPage = this.Context.GetHttpContext().Request.Query["key"]; if (FromPage == "web") { Guid imgName = Guid.NewGuid(); string connectionId = this.Context.ConnectionId; string barcodeUrl = CreateBarcode(connectionId, imgName); await Clients.Caller.SendAsync("GetConnectionId", connectionId, barcodeUrl); } else{ string connectionId = this.Context.ConnectionId; await Clients.Caller.SendAsync("GetConnectionId", connectionId); } } |
Mobile uygulamaya ait komut çeşitleri aşağıdaki gibidir: Enum olarak TypeScript’de oluşturulmuştur. Amaç kodun okunaklığının arttırılmasıdır.
1 2 3 4 5 |
export enum CommandType { LogIn = 3, OpenDoor = 1, OpenLights = 2 } |
Client Side tarafdan gelen komutu, karşılayan function aşağıdaki gibidir:
1 2 3 4 5 6 |
this.hubConnection.on("GetCommandId", (commandId) => { if (commandId == CommandType.LogIn) { this.IsLogin = true; } this.commandId = commandId; }) |
Mobile tarafta Ionic 4.0 Cordova Tab template aşağıdaki gibi oluşturulur.
1 |
ionic start mobileSignalR tabs —cordova |
IOS tarafında yetkiler, örneğin camera ya da resimlere erişim gibi, “MyApp-nfo.plist” dosyası altına aşağıdaki gibi tanımlanır.
1 2 3 4 5 6 7 8 9 |
<key>NSCameraUsageDescription</key> <string>The camera is used to scan QR codes.</string> <key>NSMainNibFile</key> <string></string> <key>NSMainNibFile~ipad</key> <string></string> <key>UILaunchStoryboardName</key> <string>MainViewController</string> <key>UIRequiresFullScreen</key> |
Ionic üzerinde, buttona basılınca çalışacak komutların Html karşılığı aşağıdaki gibidir:
1 2 3 4 5 6 7 8 9 10 |
<ion-list lines="none"> <ion-header> <ion-button (click)="scanBarcode()" style="width: 100%; color: grey" *ngIf="_clientConnectionId==null">Barkod Okut</ion-button> <ion-button (click)="setCommand(1)" style="width: 100%" *ngIf="_clientConnectionId!=null">Kapıları Aç</ion-button> </ion-header> <ion-header> <ion-button (click)="setCommand(2)" style="width: 100%" *ngIf="_clientConnectionId!=null">Far yak</ion-button> </ion-header> </ion-list> |
Tüm proje canlı olarak IOS mobile bir telefona XCODE ile derlenip, publish edilmiştir. Ayrıca Mobile cihazın da ekranı yansıtılması ile, ufak bir demo gerçekleştirilmiştir.
Bu workshop’da, Web (Front End), Socket (Back End) ve son olarak Mobile platformlar için uygulama geliştirme rolleri ve yöntemleri, bu işe yeni başlıyan arkadaşlara ilham vermesi amacı ile geliştirilmiştir. Ayrıca üzerinde konuşulan .Net Core 2.0, SignalR, Ionic 4, Angular 7, TypeScrip gibi teknolojiler, kendilerine özgü platformlarda tanıtılmıştır. Katılımcıların yoğun ilgisi, sunum sırasındaki akıl dolu soruları ve workshop sırasında koda olan katkılarından dolayı hepsini teker teker kutlar, teşekkürü bir borç bilirim.
Geldik bir seminerin daha sonuna, yeni bir seminerde görüşmek üzere hepinize hoşçakalın.
Source Code: http://www.borakasmer.com/projects/devnot.zip
Uygulamanın son hali aşağıdaki gibidir:
Son Yorumlar