7 Ağustos 2019 Çarşamba

ngrok tek process'te birden fazla tünelleme yapmak


Bir süredir ngrok kullanarak mobil geliştirme yapıyorum. ngrok kullanmam gereken 2 adet backend uygulaması var ve şimdiye kadar tek tek ngrok komutlarını yazıp çalıştırıyordum, ngrok ise pro sürümünde aynı anda 2 process'ten fazlasına izin vermiyor. Yani ben 2 process'i de kaplıyordum ve ngrok pro'yu beraber kullandığım uzmanım da umurumda olmuyordu :D :D .

Sonra bu problem ile ilgili uzmanımla problem kabul seansları yaptık ve problemi kabullenebildim :P

Tedavi süreci ise şöyle oldu;

vs code'da ngrok yml dosyasını açtık.
code ~/.ngrok2/ngrok.yml


İki process'imi de buraya şu şekıl tanımladım;

authtoken: 3s4PZenginlerinKullandığıNgrok'tanJGxwK
region: eu
console_ui: true
tunnels:
  birinci_backend:
   proto: http
   addr: 4033
   subdomain: birinci_backend
  ikinci_backend:
   proto: http
   addr: 4034
   subdomain: ikinci_backend


Artık 
ngrok start --all
dediğimde iki backend'im de yayında ve tek process kullanıyorlar.


Bonus;
fish'e de kısayol ekleyelim.
code ~/.config/fish/config.fish

...
alias ngup="ngrok start --all"
...

Artık fish'e ngup yazıp iki tünellememi de kullanıp ikinci process'i uzmanıma bırakıyorum. Böyle de iyi bir insanım. :p :P :p :P


6 Nisan 2019 Cumartesi

Firebase Cloud Functions Parsing error



Geliştirdiğim mobil uygulamanın kendine ait bir API'ı yok şuanda maalesef, başka bir uygulamanın API'ını kullanıyorum. Kendi API'ım da olacak inş ancak o zamana kadar versiyon güncellemelerini kontrol edebileceğim ufak, şirin bir metod'a ihtiyacım vardı.

Ne yapsam diye düşünürken çok yakın zamanda şirket içi eğitimde öğrendiğimiz azure'un serverless'inin function'larını kullanabilirim diye düşündüm. Sonra hali hazırda Firebase kullandığım için Firebase'in functions'ını inceledim ve direkt oraya yazayım diye karar verdim.. :)

Az yazdım, uz yazdım, dere tepe bir türlü odaklanamayarak ve uzun uzun yazdım ama sonunda bitti ve deploy aşamasına gelebildiiim :) 

Ama derin bir nefes alarak firebase deploy --only functions komutumu çalıştırdığımda başından beri yakamda olan mono lanetini yine başımda buldum. Şöyle bir hata vermekteydi;

firebase deploy --only functions

=== Deploying to 'my-api'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint /Users/monolara/Desktop/git/MyAPI/functions
> eslint .


/Users/monolara/Desktop/git/MyAPI/functions/index.js
  16:36  error  Parsing error: Unexpected token =>

✖ 1 problem (1 error, 0 warnings)

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! functions@ lint: `eslint .`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the functions@ lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/monolara/.npm/_logs/2019-04-06T13_28_06_446Z-debug.log

Error: functions predeploy error: Command terminated with non-zero exit code1

Having trouble? Try firebase deploy --help

Kızdığı şey async metodlarımdı. Ama nasıl olurdu, quickstart örneklerinde dahi async yazmışlardı ve "localimde çalışıyor"du.

Araştırdım. Ve sorunun firebase-functions'ın benim için oluşturduğu default projede ecmaVersion'ın 6 olarak geldiğini ve bu versiyonda async metodların olmadığını öğrendim. Kısaca çözüm;

.eslintrc.json dosyamızdaki ecmaVersion değerini 2017 ile değiştirmekte. Yani şöyle;
"parserOptions": { // Required for certain syntax usages "ecmaVersion": 2017 },

Bir de package.json dosyamıza şunu da eklemek gerek;
"engines": { "node": "8" },

Bir mono lanetini daha böyle aşıp güzel güzel deployumuzu yaptık. Darısı diğer lanetlere :)

10 Ekim 2018 Çarşamba

Adding custom gestures to Xamarin.Forms VisualElements with Renderer


Tek yapmak istediğim label'ıma uzun basılı tuttuktan sonra içindeki text'in kopyalanmasıydı. Haliyle gesture'lara baktım ancak xamarin.forms içinde hali hazırda "longtap" gibi bir gesturerecognizer olmadığını gördüm..

Haliyle ben de "LAYN!" deyip özel, uzun basılabiliritesi olan bir label yaptım. :) Güzel örneği bulunca hepsini ekleyesim de geldi ama sonra dedim boşver mono, zaten örnek var starla geç.
Hemen unutmadan kaynağı ekleyeyim;


Forms;
using System;
using Xamarin.Forms;

namespace GestureRendererSample
{
    public class MyLabel : Label
    {
        public MyLabel()
        {
        }
        public Action OnLongTap { get; set; }
    }
}

Android;

LabelRenderer;
using System;
using Android.Content;
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(MyLabel), typeof(MyLabelRenderer))]
namespace GestureRendererSample.Droid
{
    public class MyLabelRenderer : LabelRenderer
    {
        private readonly GestureListener _listener;
        private readonly GestureDetector _detector;

        public MALabelRenderer(Context context) : base(context)
        {
            _listener = new GestureListener();
            _detector = new GestureDetector(context, _listener);
            #region LongPressedtoLabel
            //Bu kısım biraz eksik kaldı maalesef acele iş fln durumları. En hızlı çözümü messaging center ile buldum, tabii ki geçici :)
            MessagingCenter.Unsubscribe<string>(string.Empty, "LongPressedtoLabel");
            MessagingCenter.Subscribe<string>(string.Empty, "LongPressedtoLabel",
            (sender) =>
            {
                try
                {
                    var control = ((MALabel)this.Element);
                    if (control?.OnLongTap != null)
                    {
                        control.OnLongTap();
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.LogError(ex);
                }
            });

            #endregion
        }

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

            if (e.NewElement == null)
            {
                this.GenericMotion -= HandleGenericMotion;
                this.Touch -= HandleTouch;
            }

            if (e.OldElement == null)
            {
                this.GenericMotion += HandleGenericMotion;
                this.Touch += HandleTouch;
            }
        }

        void HandleTouch(object sender, TouchEventArgs e)
        {
            _detector.OnTouchEvent(e.Event);
        }

        void HandleGenericMotion(object sender, GenericMotionEventArgs e)
        {
            _detector.OnTouchEvent(e.Event);
        }
    }
}


GestureListener;
using System;
using Android.Views;

namespace GestureRendererSample.Droid
{
public class GestureListener : GestureDetector.SimpleOnGestureListener
{
public override void OnLongPress(MotionEvent e)
{
MessagingCenter.Send(string.Empty, "LongPressedtoLabel");
base.OnLongPress(e);
}

public override bool OnDoubleTap(MotionEvent e)
{
return base.OnDoubleTap(e);
}

public override bool OnDoubleTapEvent(MotionEvent e)
{
return base.OnDoubleTapEvent(e);
}

public override bool OnSingleTapUp(MotionEvent e)
{
return base.OnSingleTapUp(e);
}

public override bool OnDown(MotionEvent e)
{
return base.OnDown(e);
}

public override bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
return base.OnFling(e1, e2, velocityX, velocityY);
}

public override bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
return base.OnScroll(e1, e2, distanceX, distanceY);
}

public override void OnShowPress(MotionEvent e)
{
base.OnShowPress(e);
}

public override bool OnSingleTapConfirmed(MotionEvent e)
{
return base.OnSingleTapConfirmed(e);
}
}
}


iOS;
using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(MyLabel), typeof(MyLabelRenderer))]
namespace GestureRendererSample.iOS
{
    public class MyLabelRenderer : LabelRenderer
    {
        UILongPressGestureRecognizer longPressGestureRecognizer;

//UIPinchGestureRecognizer pinchGestureRecognizer;
//UIPanGestureRecognizer panGestureRecognizer;
//UISwipeGestureRecognizer swipeGestureRecognizer;
//UIRotationGestureRecognizer rotationGestureRecognizer;

        public MyLabelRenderer()
        {
        }

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

            longPressGestureRecognizer = new UILongPressGestureRecognizer(() => {
                var control = ((MyLabel)this.Element);
                if (control?.OnLongTap != null)
                {
                    control.OnLongTap();
                }
            });

//pinchGestureRecognizer = new UIPinchGestureRecognizer(() => Console.WriteLine("Pinch"));
//panGestureRecognizer = new UIPanGestureRecognizer(() => Console.WriteLine("Pan"));
//swipeGestureRecognizer = new UISwipeGestureRecognizer(() => Console.WriteLine("Swipe"));
//rotationGestureRecognizer = new UIRotationGestureRecognizer(() => Console.WriteLine("Rotation"));

            if (e.NewElement == null)
            {
                if (longPressGestureRecognizer != null)
                {
                    this.RemoveGestureRecognizer(longPressGestureRecognizer);
                }

//if (pinchGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(pinchGestureRecognizer);
//}
//if (panGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(panGestureRecognizer);
//}
//if (swipeGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(swipeGestureRecognizer);
//}
//if (rotationGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(rotationGestureRecognizer);
//}
            }

            if (e.OldElement == null)
            {
                this.AddGestureRecognizer(longPressGestureRecognizer);

//this.AddGestureRecognizer(pinchGestureRecognizer);
//this.AddGestureRecognizer(panGestureRecognizer);
//this.AddGestureRecognizer(swipeGestureRecognizer);
//this.AddGestureRecognizer(rotationGestureRecognizer);
            }
        }
    }
}


Bu da buracıkta duruversin gari