19 Eylül 2018 Çarşamba

Xamarin.iOS handling notifications at foreground or background and reaching the custom data in it


İngilizce başlıktan sonra abesle iştigal edip yazımı türkçe yazacağım. :)

Bir süredir notification'larla boğuşuyorum. Boğuşmamın nedeni ise sürekli değişen bir altyapı olmuş sanırım ve birr dolu farklı dökümantasyondaki yolları izleyip denemem gerekti. Temiz ve düzenli bilgiye maalesef ulaşamadım, zaten örnek de fazla bulabilmiş değilim.

Her neyse deneye yanıla ios kısmındaki notification yönetimini şu şekilde yaptım;

AppDelegate class'ındaki FinishedLaunching'e aşağıdaki gibi kodlar nakşedilir. Bu kısım foreground yani uygulama açıkken çalışacak kısmı ifade ediyor.



public
 override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            Forms.Init();
// … kodlar kodlar … //
// … kodlar kodlar … //

            if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
            {
                var notificationSettings = UIUserNotificationSettings.GetSettingsForTypes(
                    UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, null
                );

                app.RegisterUserNotificationSettings(notificationSettings);
            }

            // Foreground notifications için.
            UNUserNotificationCenter.Current.Delegate = new UserNotificationCenterDelegate();


            return base.FinishedLaunching(app, options);
        }





Nedir buradaki UserNotificationCenterDelegate() ? UNUserNotificationCenter'dan türetip metodlarını override ettiğimiz bir class. İşte şöyle;


public class UserNotificationCenterDelegate : UNUserNotificationCenterDelegate
    {

#region Override Methods
        public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
        {   
              // custom data böyle alınıyormuş.. bunu bir türlü bulamamıştım.      
            var customData = response.Notification.Request.Content.UserInfo;

            
// … kodlar kodlar … //
            // … kodlar kodlar … //

            switch (response.ActionIdentifier)
            {
                    // Bu actionlar custom actionlar
                    // Yani notification’a buton eklediyseniz butonun id'sine göre buralar çalışıyor.
                    //Bu ayrı bir yazı konusu. :) 
                case "approve":
                    
// … kodlar kodlar … //
                    break;
                case "decline":
                    
// … kodlar kodlar … //
                    break;
                default:
                    // Bu actionlar default actionlar
                    // Yani notification’ın üzerine tıklandığında burası çalışıyor.
                    //haliyle custom datayı en çok burada kullandım.
                    if (response.IsDefaultAction)
                    {
                        if (_notificationCustomData != null)
                        {
                            
// … custom data ile dans eden kodlar … //
                        }
                    }
                    else if (response.IsDismissAction)
                    {
                        // Buraya düşüremedim uğraşmadım da gerçi
J
                    }
                    break;
            }
            // Inform caller it has been handled
            completionHandler();
        }

        public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
        {
            try
            {
                
// … kodlar kodlar … //
                // burada da custom data böyle alınıyormuş..
                var customData = notification.Request.Content.UserInfo;
               
                if (customData != null)
                {
                    
// … kodlar kodlar … //
                }else{
                
          // uygulama açıkken de isterseniz üstten notification gösterebilirsiniz, local notification oluşturabilirsiniz vs. tüm daha elinizde.
          // bu alert kısmı None olsa idi hiç notification göstermemiş olacaktık.
     completionHandler(UNNotificationPresentationOptions.Alert);
                    }
                }                
            }
            catch (Exception ex)
            {               
                System.Diagnostics.Debug.WriteLine(ex);
            }
        }
}



Bu arada AppCenter'ı kullandık notification'lar için. İnşallah örnek bir github projesi de oluşturmak istiyorum, o zaman daha kapsamlı bir yazı yazmak isterim nasipse kısmetseee :P

Şimdilik sadecee blogun yazarından bir mum duruşuuu :D

(Burada bir karikatür vardı ama telif yerim diye kaldırdım. Herkese dava açıyorlarmış karikatür paylaşılıyor diye. Karikatürün doğasına hiç uymuyor bence bu tavır :-/ )

Hay Allah :S



15 Mart 2018 Perşembe

Xamarin.Forms Android frame'e shadow vermece


Yeyy yine Xamarin'e uğramak nasip olduu ^^

Xamarin'in çok güzel bir platform olduğunu ama hiç hakkını veremediğimi düşünmüşümdür her zaman. Artık iş konusunda daha özgür bir alana sahip olduğum için yaptığım işlerin hakkını vermek istiyorum ve bu yüzden işler biraz daha yavaş çıkıyor. :) Deadline geçmediği sürece sıkıntı yok bence :))

Şimdi hızlıca yaşadığım frame sıkıntısını nasıl çözdüğümü anlatayım, malum deadline beklemez.

Sıkıntımız xamarin.forms'daki frame arkadaşının Android'de shadow vermiyor olmasıydı. .xml ler denedim, gradient'ler bilmem ne ler denedim ama istediğim sonuca ulaşamadım. Sonrasında ise .9.png uzantısını keşfettim.

Bu uzantıda bir gölge görseli oluşturdum ve frame'imin background resource'una verdim. Sonuç gayet güzel şimdilik.



.9.png uzantılı shadow u oluşturmak için kullandığım tool; 


Burada görselimi oluşturup dosyayı shadow.9.png ismi ile android drawable klasörünün altına ekledim ve aşağıdaki gibi kullandım;


using System;
using Android.Content;
using Android.Support.V4.View;
using ShadowFrame.Droid.Renderers;
using ShadowFrame.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(ShadowedFrame), typeof(ShadowedFrameRenderer))]
namespace ShadowFrame.Droid.Renderers
{
    public class ShadowedFrameRenderer: FrameRenderer
    {
        public ShadowedFrameRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                //http://inloop.github.io/shadow4android/
                ViewGroup.SetBackgroundResource(Resource.Drawable.shadow);
            }
        }
    }
}

Öğrendiğim örnek;
https://stayrony.github.io/add-shadow-to-custom-shape-on-android/

Ayrıca çözüme ulaşmaya çalıştığım diğer yolda yani xml oluşturmaya çalıştığımda yine bayağı faydalandığım tool'u da eklemek isterim;


Daha güzel çözümleri öğretene hayır dememm 


19 Şubat 2018 Pazartesi

node.js ile bir de kik bot yazayım


Botları deneyimlemeye devam ederken kik bot'la devam edeyim dedim. Ben bi messenger, bi  telegram bilirdim öncesinde meğer ne channel'lar varmış :) hepsini deneyeceğimmm. En azından papağan seviyesinde denmek istiyorum hepsini projemiz için.

Bunda bot oluşturmak ve çalıştırmak workplace'deki kadar karışık olmadı. Hikaye kısmı bittiğine göree..

Öncelikle dev.kik.com adresine gittim. Log in olmaya çalıştığımda benden yuvarlak bir qr kod taramamı istedi.  Telefonuma kik uygulamasını indirip kodu taradım. Kik'ten Botsworth diye bir bot arkadaş hemen welcome dedi ve email adresimi istedi verify etmek için. bota email adresimi yazdım ve mail geldi. Böylece verify olmuş oldum.

Ardından benden username belirlememi istedi. Çok sinirlendim çünkü benim kullandığım, kullanacağım, kullanma ihtimalim olan tüm isimler mi unavailable olur arkadaş. Biz bile böyleysek gelecek nesilleri düşünemiyorum nasıl nickname, username sahibi olacaklar?.. Guid guid gezerler muhtemelen..

(Burada bir karikatür vardı ama telif yerim diye kaldırdım. Herkese dava açıyorlarmış karikatür paylaşılıyor diye. Karikatürün doğasına hiç uymuyor bence bu tavır :-/ Naber babun?)


Neyse 5000. yaratıcı denememde bir isim bulabildim şükür. user'ımdan sonra bot oluşturma aşamasına da geçtim. Aynı sorunu burada da yaşadım ama olmayacak bir isim bulup yoluma devam etmeyi seçtim.

Sonrasında dev.kik.com'a log in olduğunda şöyle sade bir ekran karşımıza çıkıyor.



Buradaki API Key ve 5000 sefer deneyerek oluşturduğumuz username'e ihtiyacımız var.

Bot oluşturma işlemimiz tamam olduğuna göre arkasını doldurma vakti.

Her zaman yaptığımız gibi, botumuz için klasör yaratıp termalden bu klasörün içine girip

npm init 

diyoruz ve project.json dosyamızı doldurmaya başlıyoruz. 

 Şimdi VS Code'dan klasörümüzü açıp app.js dosyamızı oluşturup kodlamaya başlayalım.

Öncelikle kik'in eşyasını ve kullanacağımız diğer component'leri kuralım.

npm install @kikinteractive/kik
npm install dotenv
npm install http

require('dotenv').config({
    path: 'settings.env'
});

let Bot = require('@kikinteractive/kik');
let http = require('http');

let bot = new Bot({
    username: process.env.KIK_BOT_USERNAME,
    apiKey: process.env.KIK_API_TOKEN,
    baseUrl: process.env.BOT_HOST
});

bot.updateBotConfiguration();

bot.onTextMessage((message) => {
    var replies = [message,"Hi dear..", "Let's start to learn.."];
    bot.send(replies, message.from, message.chatId);
});

let server = http.createServer(bot.incoming()).listen(process.env.PORT || 3978);

En basit anlamıyla bir papağan botu yapmak işte bu kadar kolay. 

Tabi projemizin ngrok'la tünelleme işlemini unutmuyoruz. 

ngrok http -region=eu -subdomain=kik-bot 3978

Ve bu adresi .env doyamıza ekliyoruz. 

.env dosyamızı da buraya eklersek;


Bu kadar basit, artık papağan botumuz hazır. Bunun üzerine koya koya gidebiliriz.

Gittim :)