til 20 temmuz 2020

  • Eğer void main async olursa widgetların geldiğinden emin olmak için html’de document ready gibi şu method kullanılır.
  • WidgetsFlutterBinding.ensureInitialized();
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Widget _defaultHome = LoginPage();

  bool _result = await AuthService.isLogged();
  if (_result) _defaultHome = HomePage();

  runApp(new MaterialApp(
      title: "App",
      home: _defaultHome,
      routes: <String, WidgetBuilder>{
        '/home': (BuildContext context) => HomePage(),
        '/login': (BuildContext context) => LoginPage(),
      }));
}
  • Eğer bir sayfanın varsayılan Navigator pop özelliğini kaldırmak ve kendi kontrolüne almak istersen şöyle bir widget var.
@override
Widget build(BuildContext context) {
  return new WillPopScope(
    onWillPop: () async => false,
    child: new Scaffold(
      appBar: new AppBar(
        title: new Text("data"),
        leading: new IconButton(
          icon: new Icon(Icons.ac_unit),
          onPressed: () => Navigator.of(context).pop(),
        ),
      ),
    ),
  );
}

formkey formun state’ini tutar. forma bir form key oluşturursan ve context statetini tetiklersen form işlemleri yapabilirsin.

form validator’ı başka bir alanda yazabilirsin.

single responsibility bir yapı bir işlem yapsın, bloc lar yalnız logic düzenlesin

final –>

future–> bir işlemi başlatırsın o yürürken aynı anda başka işlem de yapabiliyordun

future –> gelecekte olacak bir olay

stream ilerleyen zamanda aynı işlemi tekrarlayabiliyor

canlı yayın bitene kadar data transferi

çok hızlı ve düşük aralıklarla, mediaplayer’a sürekli data geliyor.

sepet uygulama yayındayken sürekli değişiyor.

asenkron yapı

Today I Learned 19.07.2020

.nette hashlenmiş veriler byte array olarak tutulur ve bunun Postgresql’de karşılığı bytea’dır. kaydedilen veriler veritabanı selectinde açıkca görünmez binary olduğu bilinir.

.net’te configurasyon dosyası appsettings’tir ona erişip sabit değerleri oradan okumak gerekir startup’ta configuration propertysi vardır başka yerden erişmek için IConfiguration dependency injection yepmak gerekir.

Vue,angular gibi SPA uygulamalarda üretilen token localstorage’da tutulur.

dotnet tool install -g dotnet-aspnet-codegenerator
dotnet tool update -g dotnet-aspnet-codegenerator

postman authorization – type bearer token kısmına aldığımız jwt’yi yapıştırırsak token ile istek yapmış oluruz.

authorize şuna bakıyor –> jwt verify’dan geçti mi? bu yüzden middleware gibi yazıyoruz.

vscode’da dosyalarınızın ikonlar ile gözükmesini isterseniz icons extension kurmalısınız

https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons

among — arasında

mixin — katma

become — haline gelmek

Vue.extends ile new Vue arasında bir fark yok

vue mixins

https://www.tutorialspoint.com/vuejs/vuejs_mixins.htm

vue workshop https://jayway.github.io/vue-js-workshop/docs/add-products.html

https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started

https://www.taniarascia.com/getting-started-with-vue/

.net core ve vue ile jwt

Json Web Token

JWT Token’da üç kısım vardır. Bu kısımlar Header, Payload ve Verify Signature’dır.

Header kısmı token tipi ve şifrelenme algoritmasını içerir.

Payload kısmı sizin gönderdiğiniz verileri mesela kullanıcı adı bilgilerini içerirbir de iat yani token’ın oluşturulma zamanını tutar.

“Bu token ne zaman oluşturuldu?” belirten bir tarih alanıdır iat.

Bu da token’ı silmek yani expire içindir. Bu Token’ın ne zaman oluştuğunu tutmalısınız ki mesela 5 dk geçerli Token’ları süre dolduktan sonra silebilesiniz.

Header ve Payload alanları base64 algoritmasına göre şifrelenir dolayısıyla geri açılıp okunabilir yani bu alanlara gizli bilgi konmamalıdır.(mesela kullanıcı şifresi burada bulunmamalı)

JWT token bir string ifadedir yani karakter dizisidir ve bu dizi içerisinde iki tane . karakteri vardır ki bu karakter string’i parçalara ayırırlar dolayısıyla iki nokta üç kısımdan oluşan bir karakter dizimiz var.

Son kısım yani Verify Signature kısmı ise sunucu tarafından veriken ve tek yönlü şifreleme ile şifrelenen bir veri yani bir string’tir. Bu sunucunuzun imzasıdır, yalnızca sunucunuz bunu bilmelidir.

JWT aslında kullanıcı bilgilerinin şifrelenmesi değil de, “bu token bu sunucu tarafından mı üretildi?” sorusunun cevabını kontrol eden bir yapıdır. Bu sayede güvenliği sağlamış olursunuz çünkü istemci HTTP isteğinde (standart olarak header’da) bu token’ı size verir siz de bunu ben oluşturmuşum demek ki bu kişi benim sistemimde yetkilidir diyerek uygulamanızda gezinmesine izin verebilirsiniz.

Bu üç parça da Header’da verilen algoritmaya göre yani varsayılan olarak hmacsha256 algoritmasına göre şifrelenir. Şifrelenmiş hali de sizin JSON Web Token’ınız olur zaten.

Demek ki sunucu imzası bilinmeden bu token’ın aynısı oluşturulamaz ve demek ki o client için başka bir token oluşturamaz. Eğer o token verify edilebiliyorsa bu sunucu imzası ile oluşturulmuş bir Token’dır. İstek geldiğinde token’a bakarak ben mi imzalamışım bunu? anlayabilirsiniz.

Genel işleyiş ise şöyledir;

  • istemci get isteği yapar login olmak ister
  • sunucu kullanıcı adı ve şifre kontrol ve onaylaması yapar eğer onay aldıysa yani bu kullanıcı adı ve şifre sistemce doğrulandıysa doğrulamadan geçmiş olur ve bir token üretir ve bu token istemciye döner
  • istemci token’ı alır ve bundan sonraki tüm http isteklerinde bu token’ı da http header içerisinde sunucuya gönderir
  • sunucu gelen isteklerdeki token’ı tanırsa bu benim istemcim çünkü elindeki token’ı ben imzalamışım der ve gezinmesine izin verir.
  • token doğrulanmazsa 401 authorize hatası döner.
  • Bu iletişim httpS protokolü ile gerçekleşmeli ki (security) güvenli bir iletişim olsun json token istemci ve sunucu arasında gizli bir bilgi olarak kalsın. İletişim esnasında gidip gelen istekler ve yanıtlar şifrelensin aradaki bir kişi bunu okuyamasın.

Not: Token bilgisini HTTP Header’da vermek zorunda değilsiniz ama entegre olduğumuz sistemlerle uyumluluk için standartlara uyarız. Bu standartlara çoğunlukla IETF karar verir.

Token güvenliği için bir süre sonra tekrar oluşturulmalı, bi sene duran bir token (bu bir token için çok uzun bir süredir) güvenlik açığı oluşturabilir. 2 sn’de bir token oluşturursak bu da matematiksel bir işlemdir ve processing power (işlem gücü) kaybettirir. Demek ki ikisinin arası bulunmalı hem güvenlik hem de hız için.

Token verify olabilmesi için verilen imzanın doğru olması gerekir yoksa token verify edemez okunamaz. Header ve Payload kısımları çözümlense de token doğrulanmış olmaz. Eğer token doğrulanmış ise bu kullanıcı authorize olmuş yani sistemde doğrulanmış yetkili bir kullanıcıdır sistemde gezinebilir diyebiliriz.

.net core ile kullanımı

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

Birkaç konfigürasyon yapmanız gerekecek

    public void ConfigureServices(IServiceCollection services)
        {
            var mySecret = Configuration["Secret"];
            var key = Encoding.ASCII.GetBytes(mySecret);

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
                {
                    options.RequireHttpsMetadata = false;
                    options.SaveToken = true;
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(key),
                        ValidateIssuer = false,
                        ValidateAudience = false
                    };
                });

            services.AddControllers();
        }

ve token’ı oluşturunuz

Not: Burada konfigürasyon dosyasından direkt okuyabilmek için IConfiguration enjekte edilmelidir.

  IConfiguration _configuration;
        public TokenController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
  var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_configuration["Secret"]);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]{
                    new Claim(ClaimTypes.Name , "userId")
                }),
                Expires = DateTime.UtcNow.AddDays(2),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            return Ok(tokenH
andler.WriteToken(token));

Sadece sunucunuzun bildiği key ise appSettings dosyasında yer alır.

JwtSecurityTokenHandler: sunucu keyini kullanarak dijital olarak imzalanmış bir token oluşturur.

Not: burada dikkat etmeniz gereken bir şey var o da sunucu imzanızı kısa verirseniz hata verecektir.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Secret": "dahauzunbirkeysecret"
}

Şöylece token üretip istemcide bunu alabilirsiniz.

Artık SPA veya mobil uygulamalarınızda token oluşturarak yetkilendirme işlemi yapabilirsiniz.

Peki bu token’ı kullanarak nasıl kullanıcı girişi sağlarız?

Eğer bir SPA uygulaması yapıyorsanız mesela angular, vue kullanıyorsanız o zaman login işlemini yaptığınızda ve api’den token aldığınızda bu token’ı local storage’a yazmanız gerekiyor, bu şekilde giriş yapıp yapmadığınızı da anlayacaksınız.

Uygulama içerisinde kullanıcı bilgilerine erişmek için de gelen token’ı decode etmeniz gerekiyor. Neden mi? Çünkü token’daki payload kısmında zaten sizin kullanıcı bilgilerinizin (claim’leri hatırlayın) encode edilmiş hali vardı, eğer bunu aynı jwt standartlarıyla decode ederseniz claim bilgilerine ulaşırsınız.

Mobil uygulamalarda ise mesela Flutter kullandığınızı düşünelim o zaman bu token’ı Shared Prefences’a yazabilirsiniz, buraya kullanıcı adı ve şifrenizi de yazabilirsiniz.

Token expire olduğunda ise tekrar üreteceksiniz.

Vue kısmında ise şöyle bir kod düşünebilirsiniz

//  src/auth/index.js

import {router} from '../index'

const API_URL = 'http://localhost:3001/'
const LOGIN_URL = API_URL + 'sessions/create/'
const SIGNUP_URL = API_URL + 'users/'

export default {

  user: {
    authenticated: false
  },

  login(context, creds, redirect) {
    context.$http.post(LOGIN_URL, creds, (data) => {
      localStorage.setItem('id_token', data.id_token)

      this.user.authenticated = true

      if(redirect) {
        router.go(redirect)        
      }

    }).error((err) => {
      context.error = err
    })
  },

  signup(context, creds, redirect) {
    context.$http.post(SIGNUP_URL, creds, (data) => {
      localStorage.setItem('id_token', data.id_token)

      this.user.authenticated = true

      if(redirect) {
        router.go(redirect)        
      }

    }).error((err) => {
      context.error = err
    })
  },

  logout() {
    localStorage.removeItem('id_token')
    this.user.authenticated = false
  },

  checkAuth() {
    var jwt = localStorage.getItem('id_token')
    if(jwt) {
      this.user.authenticated = true
    }
    else {
      this.user.authenticated = false      
    }
  },


  getAuthHeader() {
    return {
      'Authorization': 'Bearer ' + localStorage.getItem('id_token')
    }
  }
}

ve

  <!-- src/components/SecretQuote.vue --> 
  
  <template>
    <div class="col-sm-6 col-sm-offset-3">
      <h1>Get a Secret Chuck Norris Quote!</h1>
      <button class="btn btn-warning" v-on:click="getQuote()">Get a Quote</button>
      <div class="quote-area" v-if="quote">
        <h2><blockquote>{{ quote }}</blockquote></h2>      
      </div>
    </div>
  </template>

  <script>
  import auth from '../auth'

  export default {

    data() {
      return {
        quote: ''
      }
    },

    methods: {
      getQuote() {
        this.$http
          .get('http://localhost:3001/api/protected/random-quote', (data) => {
            this.quote = data;
          }, { 
            headers: auth.getAuthHeader()
          })
          .error((err) => console.log(err))
      }
    },

    route: {
      canActivate() {
        return auth.user.authenticated
      }
    }

  }
  </script>

Kaynaklar:

https://github.com/auth0-blog/vue-jwt-authentication

https://www.digitalocean.com/community/tutorials/vuejs-vue-jwt-patterns#with-vuex

https://medium.com/bili%C5%9Fim-hareketi/asp-net-core-ile-jwt-authentication-web-api-uyg-66a7d3fecb6f

https://bezkoder.com/jwt-vue-vuex-authentication/

https://bezkoder.com/vue-axios-file-upload/

https://www.buraksenyurt.com/post/jwt-json-web-token-kullanimi

https://www.buraksenyurt.com/post/AspNet-Web-API-Security-Giris-ve-Custom-Basic-Authentication-Module

https://www.gencayyildiz.com/blog/json-web-tokenjwt-nedir/

https://www.gencayyildiz.com/blog/asp-net-core-3-1-ile-token-bazli-kimlik-dogrulamasi-ve-refresh-token-kullanimijwt/

https://jasonwatmore.com/post/2018/07/06/vue-vuex-jwt-authentication-tutorial-example#auth-header-js

https://vuejsdevelopers.com/2019/04/15/api-security-jwt-json-web-tokens/

Mobil Programlama – Flutter

Sabit fotoğraf getirmek

Image.asset(
            "images/img.png"
          )

Fotoğrafı boyutlandırmak için

Image.asset(
            "images/img.png",
            width: 25,
            height: 25,
          )

Margin-Padding aralıkları vermek

 Padding(
          padding: const EdgeInsets.all(5.0),
          child: Text("metin"),
        )

Kenar boşlukları (Edge Insets) all methodu her kenara parametresindeki değer kadar her kenardan iç boşluk bırakır. Parametresi double veri tipinde bir değerdir bu yüzden “.” ile veya direkt yazılabilir (5 ve 5.0 gibi)

all methodu yerine yerine only methodu kullansa idik

EdgeInsets.only(top: 5.0, right: 10.0)

Hem margin hem padding verebileceğiniz web arayüzünde yani html ve css kullanırken div oluşturmaya benzeyen bir container yapısı var. Container yani kutu, bu kutu içerisine elemanlar koyup boşluklarını ve bazı diğer özelliklerini ayarlayabilirsiniz.

Container(
        margin: EdgeInsets.all(25.0),
        padding: EdgeInsets.only(top: 20),
        child: Text("metin")
)

Genel olarak sayfa içinde Scaffold ile iskeleyi kurduktan sonra bir container içinde diğer elemanlar yerleştirilir.

Bu Container’a yani kutunuza genişlik ve yükseklik de verebilirsiniz.

Container(
        margin: EdgeInsets.all(25.0),
        padding: EdgeInsets.only(top: 20),
        width: 300.0,
        height: 300.0,
        child: Text("metin")
)

Bu size dış kenar boşlukları her kenardan 25px ve iç boşlukları sadece yukarıdan 20px, genişliği 300px ve yüksekliği 300px olan bir kutunun içerisine “metin” yazacaktır.

Container’a renk vermek ve kenarlarını yuvarlamak gibi özellikleri de BoxDecoration ile ekleyebilirsiniz bunu html deki style içerisine yazıyor gibi veya harici bir css dosyasında yazıyor gibi düşünebilirsiniz.

Container(
      margin: EdgeInsets.all(25.0),
      padding: EdgeInsets.only(top: 20),
      width: 300.0,
      height: 300.0,
      child: Text("metin")
      decoration: new BoxDecoration(
        color: Colors.red,
        shape: BoxShape.circle,
      )
    )

Yazıyı ortalamak isterseniz ilk aklınıza gelen padding değeri vermek olabilir ancak daha iyi ve daha kolay bir yöntem var flutter’da bunun için Center widget’ını kullanırız ortalamak istediğimiz elemanı Center widget’ı içine yazarız ve ortalama işlemi tamamlanır.

Container(
      margin: EdgeInsets.all(25.0),
      padding: EdgeInsets.only(top: 20),
      width: 300.0,
      height: 300.0,
      child: Center(
                child: Text("metin"),
              ),
      decoration: new BoxDecoration(
        color: Colors.red,
        shape: BoxShape.circle,
      )
    )

metninizi de stil vererek özelleştirmek isteyebiliriz.

Container(
      margin: EdgeInsets.all(25.0),
      padding: EdgeInsets.only(top: 20),
      width: 300.0,
      height: 300.0,
      child: Center(
                child: Text(
                  "metin",
                  style: TextStyle(fontSize: 20.0),
                ),
              ),
      decoration: new BoxDecoration(
        color: Colors.red,
        shape: BoxShape.circle,
      )
    )

style parametresi eklemesiyle metninizin font büyüklüğünü değiştirmiş olabilirsiniz. metnin fontunu değiştirmek isterseniz style’da bunun için de bir parametre var fakat bunun için fontu assets dosyanıza eklemeniz lazım bu ayrı bir konu. şimdilik sadece assetsde eklenmiş ve flutter’ın tanıdığı bir font üzerinden gidelim ve metnimizin fontunu değiştirelim.

Container(
      margin: EdgeInsets.all(25.0),
      padding: EdgeInsets.only(top: 20),
      width: 300.0,
      height: 300.0,
      child: Center(
                child: Text(
                  "metin",
                  style: TextStyle(
                    fontSize: 20.0,
                    fontFamily: "Roboto",
                  ),
                ),
              ),
      decoration: new BoxDecoration(
        color: Colors.red,
        shape: BoxShape.circle,
      )
    )

Eğer Container elemanınıza bir kenarlık vermek isterseniz.

 border: Border.all(color: Colors.blueAccent)

Html ve CSS yazarken pozisyonlamaya alıştıysanız flutter’da bunu yapmak isteyebilirsiniz bunun için şöyle bir widget mevcud.

              Positioned(
                child: Container(
                  color: Colors.blue,
                  child: Text(
                    "metin",
                    textAlign: TextAlign.center,
                    style: TextStyle(fontSize: 30),
                  ),
                ),
                left: 70,
                top: 0,
              ),

Sıralı verileri görüntülemek için en sade kullanımıyla ListView

ListView(
                  children: <Widget>[
                    Container(
                      height: 50,
                      color: Colors.amber[600],
                      child: const Center(child: Text('Entry A')),
                    ),
                    Container(
                      height: 50,
                      color: Colors.amber[500],
                      child: const Center(child: Text('Entry B')),
                    ),
                    Container(
                      height: 50,
                      color: Colors.amber[100],
                      child: const Center(child: Text('Entry C')),
                    ),
                  ],
                ),

Otomatik oluşturmak için builder kullanılmalı

Eğer bir metin girişine ihtiyacınız varsa TextFormField elemanını kullanabilirsiniz.

Eğer metin girişinde birkaç satırlık veri almak istiyorsanız yani html’deki textarea elemanına ihtiyacınız varsa TextFormField içerisinde maxLines parametresini kullanabilirsiniz.

Bu metin girişinde yazı ortalansın istiyorsanız da TextFormField elemanının textAlign özelliğini kullanabilirsiniz.

TextFormField(
                textAlign: TextAlign.center,
                maxLines: 3,
                decoration: InputDecoration.collapsed(
                  hintText: "Mesajınız",
                ),
              ),
  • Kullanıcı girişi yapacağımız bir uygulamada api kullanacağımızı varsayalım, bu noktada biz her uygulamayı açtığımızda giriş yapmamalıyız demek ki bizim kullanıcı bilgimiz bir yerde saklanıyor olmalı ve uygulamayı açtığımız zaman o bilgiler ile giriş yapıyor olmalıyız. Demek ki uygulama açılırken hafızadaki kalıcı bilgiler ile bir kontrol yapmalıyız. Bu kalıcı bilgiler SharedPrefences altında durur.

Flutter’da cihazın boyutunu almak

MediaQuery.of(context).size.width

Dartta kurucu methodlar . ile oluşturulur.

class User {
  String id;
  String username;

  User(this.id, this.username);

  // constructer böyle oluşturuyor flutter
  // json map olarak geliyor
  User.fromJson(Map json) {
    id = json["id"];
    username = json["username"];
  }

  Map toJson() {
    return {"id": id, "username": username}; //map böyle oluşur
  }
}

Dart’ta http servislerine bağlanmak için http paketi yüklenir

pubspec.yaml içine yazılır ve pub get yapılır

dependencies:
  flutter:
    sdk: flutter
  http: 

Dartta alias ile referansa erişirken daha temiz bir hal alır.

import 'package:http/http.dart' as http;

Networking

emulator aynı networkte farklı ip adresi kullanıyor

senin mevcud bilgisayarın(sunucun) aynı networkte farklı ip adresi kullanıyor.

Bu yüzden http isteği yaparken url’e localhost dememelisin.

localhost dersen emulator’ün localhost’u olur android işletim sisteminin localhost’u ve dolayısıyla api’ye erişemezsin.

10.0.0.2 emulator’ün kendi adresi

Form Oluşturmak

import 'package:flutter/material.dart';

class LoginView extends StatefulWidget {
  @override
  _LoginViewState createState() => _LoginViewState();
}

class _LoginViewState extends State<LoginView> {
  
  var formKey = GlobalKey<FormState>(); 
  
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

aşağıdaki kod doğru çalışmıyor düzenlenecek

var options = new Options;

options.headers['Authorization'] = 'bearer $token';
options.contentType = 'application/json';

String url = "https://www.myurl.com";

Map<String, String> qParams = {
  'param1': 'one',
  'param2': 'two',
};

var res = await http.get(url, options: options, queryParameters: qParams);

text editing controller


Dart ile Programlama

Future


Map


List

List<dynamic>


http


class


Dart’ta her nesne referans tabanlıdır o yüzden varsayılan değer diye bir şey yoktur her değişken ilk tanımlanıp henüz atama yapılmadığında null değerine sahiptir.



Merhaba Flutter!

4 tane primitive değişken tipi var

  • String
  • double
  • int
  • bool
  • var yazdığınızda python ve js gibi dillerde değişken tipini runtime’da değiştirir.
  • nesneye yönelimli sıkı dillerde c#, java, dart hata verir.

  • material → android görünüm
  • cupertino → ios görünüm’e daha yatkın.

  • Widget’lar özünde sınıflardır.
  • Widget ağacı
  • her şey widget ağacı üzerine kurulmaya zorunludur bu yüzden title = string ifade diyemezsin Text widget’ı içine almalısın.

  • hot reload → uygulama içerisindeki değişen kısımlara bakarak değiştirir.

  • hot restart → apk yı yeniden oluşturmaz ama widget ağacını yeniden kurar

  • şart blokları → uygulama dallanmalarıdır
  • if — switch
  • hangi güzergahtan gidelim?
  • ilk girdin login oldu mu? → evet/hayır
  • localstorage.keys[“token”]

  • = atamak
  • == eşit mi?

  • RaisedButton
  • BUTTON diyince aklına eventler gelmeli

  • gesture detector

  • AlertDialog

  • Context Yapısı
  • context : senin mobil uygulamana dair bilgiyi tutan yapıdır
  • nedir ? yapı ne yapısı? flutterda tanımlı. sadece flutter mı? hayır felsefede var bağlam bağlam nedir? senin çerçeven yani kar diyosun hangi alanda meteoroliji de mi? ticarette mi nasıl anlayayım ben bu karı?
  • javada da vardı sanırım context zaten c#da da var nerede?
  • ne ?
  • nerede? build context 
  • sql de var
  • bu widget hangi ağaca ait?


Flutter: Yerel Veritabanı Kalıcı Veri (sqlite)

Merhabalar, 

Yazılım ile meşgul olanların bildiği üzere verilerimizi düzenli olmalı ulaşım ve filtrelemenin kolay olması gibi nedenlerden veritabanlarında saklıyoruz.

Mobil uygulamayı kullanan kişinin interneti her vakit açık olmayabilir bununla birlikte siz dakika kullanımı, bakiye tutarı gibi anlık değişen veriler tutmuyorsanız telefonun internet erişimi olmadığı zamanlar da uygulamanız açılır olabilmeli hatta önceki eriştiği verileri de görebilir olmalıdır. 

Mesela twitter uygulamasında ağ erişimimiz varken yeni atılan twitleri çekebiliriz daha sonra ağ erişimimiz kapalı iken twitter uygulamasına girdiğimizde eski gördüğümüz twitleri görmeye devam ederiz. Bu veriler web servislerinden gelmiyor belli ki ama nereden geliyor? İşte bu gibi durumlarda yerel veritabanları karşımıza çıkmaktadır.


Araçlar

SQLite 

Veritabanlarını kullanırken sql ile sorgular eklemeler düzenlemeler yaparız bunun için bazı ürünler vardır postgresql mysql mssql gibi.. Bu ürünler gibi yerel bir veritabanında sql ile işlem yapmamızı sağlayan sqlite vardır. sql tabanlı bir veri sorgulama dili.


sqflite

yazdığımız programda veritabanına erişebilmek için bazı kütüphaneler kullanırız mesela .NET dünyasında ADO.NET vardır ve bizim veritabanına bağlanma, veri yazma , veri okuma ve silme gibi işlemleri yaparız.


Sözlük Uygulaması

Senaryo

Kullanıcı uygulamada kelime kaydeder, kaydettiği kelimeleri listeleyebilir ve filtreleyebilir.


İş Kuralları

  • kullanıcı sözlüğe yeni kelime ekleyebilir
  • kelimelerin tamamı listelenebilir ve baş harflerine göre gruplanır alfabetik sıralanır
  • kullanıcı kelime araması yapabilir
  • kelimenin kendisi, açıklaması ve benzersiz kimliği vardır.

Lab

Gerekli paketler 

path | Dart Package
A comprehensive, cross-platform path manipulation library for Dart. The path package provides common operations for…pub.dev
sqflite | Flutter Package
SQLite plugin for Flutter. Supports iOS, Android and MacOS. Support transactions and batches Automatic version…pub.dev


Kelime Nesnesi



Flutter ile Mobil Uygulama Geliştirmek

Flutter’da ekranda gördüğünüz her eleman bir widget’dır.

Widget’lar veriye göre anlık değişen(stateful) ve veriye göre anlık değişmeyen,veriye bağımlı olmayan (stateless) olmak üzere ikiye ayrılır.


Eğer bazı verileri alıp bir listede “sadece gösterecekseniz” bu stateless bir elemandır. 

Eğer bir listede verileri gösterip sayfa yenilendiğinde (yani mobilde alışkın olduğunuz yukarı doğru çekildiğinde) liste elemanlarının değişmesini yani eklenen elemanların ekranda gözükmesini istiyorsanız yani dinamik bir liste yapısı kurmak ve buna bağlı (veri değiştiğinde değişen )bir eleman hazırlamak istiyorsanız bu is stateful bir widget’dır.


statefull widget’ın bir initState methodu olur açılırken çalışan

bu method asenkron olamaz

çünkü zaten başka işlem olmadan onun açılması gerekiyor.

eğer initstate durumunda awaitable bir method çağırmak isterseniz bu methodu ayrı bir fonksiyonda çağırıp o fonksiyonu init state’e alınız.

preferences.setString(“key”, “value”)

state bir değişken olarak tanınlanır.

state’i çalışma anında değiştirmek için

o widget içinde istediğiniz bir yerde setstate methodunu açın ve içerisinde gerekli atama işlemini gerçekleştirin


İki elemanı üst üste koymak isterseniz burada yığın elemanını kullanmalısınız.

Widget: Stack


Not: Eğer sayfada liste ile başka elemanları birlikte kullanmak isterseniz listeyi bir kapsayıcı eleman içerisine yerleştirmelisini.

Yani listeniz Expanded Widget’ı içinde yer almalıdır. Aksi halde hata ile karşılaşabilirsiniz.


Renk kullanmak için Color nesnesi ile red, green, blue, opacity formatında veya Color(“”) içerisine hexadecimal formatta renk belirtirseniz bunu uygulayacaktır.


Ekranda göstermek ve aşağı inildikçe devam etmesini istediğiniz elemanlarınız varsa ki buna liste denilir. Bunu ListView Widget’ı ile gösterebilirsiniz.

ListView

  • children parametresi vardır ve dizi, liste alır. listenizi uzun bir bina olarak düşündüğünüzde bu elemanlar bu binanın katlarıdır. Listenizi bir duvar olarak düşündüğünüzde bu elemanlar bu duvarın kiremitleridir. Bu yüzden ListView children parametresi ListTile’lardan oluşan bir dizidir.
  • ListTile Widget’ının parametrelerinden biri “title” parametresidir ki bu parametrede liste elemanınızda yazılacak ana metni seçersiniz.
  • Bu listenizin çocuk elemanlarını verdikten sonra özelleştirebilirsiniz mesela alışıldık olan aşağı doğru kayan bir liste değil de scroll’un yana doğru hareket ettiği ve yana doğru uzayan bir liste yapabilirsiniz.
  • Ve hatta bence liste içinde liste yapısı oluşturarak hem aşağı doğru hem her elemanının yana doğru kaydığı bir liste planlayabilirsiniz.
  • ve mesela listenizin tersten doğru sıralanmasını isterseniz ki api kullanıyorsanız zaten bu veriyi doğru sırayla alırsınız, yine de ihtiyaç durumunda reverse parametresini kullanarak listenizi tersten sıralayabilirsiniz.

Floating action button → ile sağ alt ekleme butonu oluşturabilirsiniz


eklediğiniz elemanları bir kısmı geçmiş tarihlerde kaldı ve bu elemanlar tıklanılmasın istediğinizden ve bunu kullanıcıya belirtmek istediğinizden onların opaklıklarını düşürüp daha saydam bir hal alsın istediniz.

Opacity Widget’ını kullanarak bunu gerçekleştirebilirsiniz.


Flutter’da bir takım bilgileri göstermek ve bu bilgileri düzenleme imkanını da kullanıcıya vermek isterseniz bu noktada formları kullanmanız gerekecektir.


Flutter’da mesela bir sayfa oluşturdunuz ve 2 seçeneğiniz var mesela bir spor salonunun uygulamasında kişi giriş yaptığında fitness ile ilgili bilgileri mi görmek istiyor yüzme ile ilgili bilgileri mi görmek istiyor? Bu durumda yüzme ve fitness diye iki button oluşturursunuz ve bunlara tıklandığında ilgili sayfaya gider. Burada kullanacağınız eleman Button Widget’dır.

Hazır animasyonlu ve tasarlanmış bir button isterseniz Raised Button Widget’ını kullanabilirsiniz.

Bir propertysi : decoration 

bir propertysi : shape shape border tipinden bir değer alır mesela OutlineInputBorder alır.

Raised Button’a benzer bir widget da flat button widget’ı o da saydam bir yapı ile geliyor.

En güzeli de genelde sayfanın sağ altında gördüğünüz floating action button widget’ı.

Bu widget Icon propertysi alır Icon(Icons.x) ile bu button’a material app tasarımı içerisindeki icon’lardan verebilirsiniz.

Not: Color, form vs elemanları hangi tasarıma göre çekiyor? Bunu temadan çekiyor ve temamız da materialApp dir.

material.io

etrafı çerçeveli bir button isterseniz de outline button kullanabilirsiniz.


Kendim tasarlamak istiyorum diyorsanız html’deki div vazifesini gören

Container widget’ı ile iştigal etmeniz gerekiyor

decoration propertysine bir box decoration verebilirsiniz.

gradient:lineargradient

 buna colors dizisi vereceksin

container’a height width vermedikce tüm sayfayı doldurur.

stops ile de gradient ayarı yapabiliyorsunuz


Hizalama:

Eğer html’deki div yapısı olan Container’ı kullandığınız ve konumlandırmak yani bir nevi alignment vermek istiyorsanız flutter sarmal yapısındaki widgetlardan biri içerisine almalısınız.

eğer ortalamak istiyorsanız bu widget → Center’dır

eğer hizalamak istiyorsanız bu widget → Align’dır

ve align widget’ı içerisindeki aligment propertysine bir alignment enum değeri girmelisiniz.

bununla birlikte align sayısal bir değer de alabilir

kutunun

en altı 1 — en üstü -1

en solu 1 – en solu +1 dir

  • – 0.75 -0.75 verirseniz sol üstte
  • 0.5 0.5 verirseniz ortaya değil sağ alta yakın
  • 0 0 verirseniz ortaya
  • +1 +0.80 verirseniz tam sağ hafif alta vs konumlanabilir
  • -1 +1 sağ üsttür

birincisi yatay ikincisi dikey konumlandırmadır.

bu yapılandırmayı stack içerisinde de kullanabilirsin ki kullandık.


Gesture Detector → jestinizi yakalayan ve fonksiyon çağıran eleman

child propertysine tıklanılacak elemanı

ontap


Navigator.push() ekleyebilirsiniz.

Navigator.push(context,

MaterialPageRoute(builder: (context) => MainApp()));



Nasıl hızlı yazabiliriz? Snippet’ları kullanarak


Stateless Widget → veriyi alır ve gösterir ama sayfadaki state durum değişecekse statefull yapmak gerektir.


Not: Font ekledikten yükledikten sonra uygulamayı bi kapatıp açarsanız başarılı bir sonuç göreceksinizdir bazen uygulama içerisinde fontu güncellemesi uzun sürüyor.


Sayfa Değiştirmek


Uygulamanızda muhtemelen bir tablo gibi ilişkili olmayan ama anahtar değer gibi tutmak isteyeceğiniz ve her yerde kullanılacak verileriniz olacaktır. Mesela giriş yapan kişinin ismi ve şifresi ya da token’ı kişinin rolü vs bunlar tüm uygulama için ortak parametredir. ve bunları SharedPreferences’da android için apple için ise NSUserDefaults de tutarız.

singleton tasarım desenini kullanarak bir nesne üretme yaparız ki birden fazla nesne üretilmesin bu shared preferences’dan. 

öncelikle pub dev’den modülü kurunuz

bunu yaptığınız zaman shared preferences’ın projenize dahil olduğunu ve çağırabildiğinizi göreceksiniz

await SharedPreferences.getInstance()

getString ile de çağırısınız

setString ile de atama yaparsınız.


singleton nesnelerin splash’de init edilmesi mantıklı sanırım


Adding a splash screen to your mobile app
Splash screens (also known as launch screens) provide a simple initial experience while your mobile app loads. They set…flutter.dev
Flutter’da Floor Kullanımı — Sql Kütüphanesi
Flutter’da uygulama geliştirirken bazı verileri lokalde tutmak isteyebiliriz. Bu verileri lokalde bir veri tabanında…medium.com
Offline first with Flutter
Welcome to the 21st century where 5G, hotspots and mobile internet is available everywhere. But what if not ?medium.com
jogboms/flutter_offline
A tidy utility to handle offline/online connectivity like a Boss. It provides support for both iOS and Android…github.com
Realm: Create reactive mobile apps in a fraction of the time
XCode 10.0 or higher Target of iOS 9 or higher, macOS 10.9 or higher, or any version of tvOS or watchOS If you’re…realm.io

Flutter Widget’lar Nedir?

Flutter 1 — Temel Liste Gösterimi

Flutter öğrenmeye başladığımda bir çok yeni ve gelişmiş özelliğin olduğunu ve bir konuda birden fazla yaklaşım olduğunu farkettim bu yüzden küçük hedef uygulamalar ile geliştirmeye başlamak her zaman daha iyidir diye düşünüyorum.

Hedef:

Meyveler listesi oluşturmak

Neleri Öğrenmeliyim?

  • Widget
  • List
  • ListView
  • Navigation
  • Pass argument page to page
  • Image show

Widget, bir flutter UI’ının her bir parçasıdır. Flutter kendi dökümanında da bahsettiği gibi Widget yapısında React’den ilham almıştır.

Altında yatan fikir ise başta söylediğimiz gibi UI’ın bu widget’lardan oluşmasıdır.

Widget durumu değiştiğinde çerçeve önceki durumdan sonraki duruma geçişte ağaç yapısında olması gereken asgari değişikliği bulur ve uygular.

Dökümanda öğrendiğim ingilizce kelimeler

acquainted — tanışmış 

out of widgets — widget’lardan

should look like — nasıl görünmesi gerektiği

against — karşı

determine — tanımlamak

underlying — altında yatan

transition — geçiş

experimental — deneysel

experience — tecrübehttps://nasrbilisim.wordpress.com/media/465ed9c5dcbca30643f093bbfe257e68

squished — ezilmiş

occupy — işgal etmek meşgul etmek

explicitly — açıkca

wraps — giydirme

fraction — kesir

remaining--kalanalmost -- hemen hemen neredeyse

dua

imkan dairesi ve vücub dairesinin kanunları farklı

dua aidiyet hissettirir, çarkları harekete geçirir

muhabbet, gül diken

komutan hazır olur musunuz demez, celali tecelli

gözümüz de gönlümüz de sizde ha

60 sahife mesnevi

mahv ve isbat — isbat yazmak

insanda 50trilyon hücre 3bin değişiklik oluyor bir saniyede

bende meydana gelen 50trilyon*3bin değişiklik

bir önceki ben silindim bir sonraki ben yazıldım

öyle olmasa 10 sene önceki ben aynı olurdum

her an bir yaratmada

her şey kendiliğinden gibi anlatılıyor nimetten nimeti vereni anlamaya ihtiyacımız var

halı programı imam-ı mübin – Allahın ilmindeyken

halının elementlerle yazılması kitab-ı mübin – yaradılış

bilgisayar tuşuna bastın çekmeye devam ediyor

20. mektup 2. makam 9. kelime

muhit bir ilim

hüve nüktesi odadaki radyolar aktarımdaki intizam

acizin mucizevi işler yapması arkasındaki zatı gösteriyor Bismillah de

esbab perdedar-ı dest-i kudret ola

kainat onsuz yapamaz isteyen de aciz istenen de

kavun

gemi

ism-i kayyum saat mekanik –

insan – medeniyet / ahkam – Kur’an

19.mektup – peygamber mucize

fabrika elektrik

niçin şeriki olsun ki

beni yaradana niçin ibadet etmeyeyim?

niçin vahid olan Allah’ın şerikini iptal etmeyeyim.

nuh muh işi değil

saat – ahiret – çalışan saati saniyesinden anlarsın

dirilmemek üzere toprak altında kalmayacaktır

La ilahe illallahu vahdehu la şerike leh

akıl

toprağa girip her amelinden sual olunmamak ve uyandırılmamak üzere yatıp saklanmayacaktır. ismi hafiz ve hakk

halıkımız bize en büyük muallim ve en mükemmel üstad ve en şaşırmaz ve şaşırtmaz en doğru rehber olarak Muhammedi Arabî asm’ı tayin etmiş

evet haşir gibi en acib ve en dehşetli ve tavrı aklın haricinde bir mesele ancak ve ancak böyle harika iki üstadın dersleriyle halledilir anlaşılır

halletmek ve anlamak için üstad lazım Kur’an ve Peygamberimiz asm en büyük iki üstaddır arı da üstaddır 70bin zatlardan ders almış

bozulmuş aklı yetişmediği şeye hurafe der

iptidai derslerde izah az olur, eski kavimler

mahiyet-i insaniyenin bir hizmetkarı olan kuvvei hayaliye

mahiyet nedir?

akıl en büyük nimettir (hadis)

-akıl en ehemmiyetli cihaz- risaleinur

ergenlikteki uyanma 8. söz biri buraya getirdi

sebep arıyor insan koronanın arkasında ne var diyoruz ne sebep oldu komplo teorileri kuruyoruz insan ister istemez bir sebep bir teori kuruyor doğru olması önemli

insan büyük resmi görmeye çalışıyor fıtratı bu

renkleri göremeyen yemek istemiyor ünsiyet çünkü içi

renkleri görmeyen bir adam varmış

bu filmin devamı var her şeyi burada yapmana gerek yok

04.04.2020

bu istidatların inkişafı elbette bir hareket ister bir muamele iktiza eder

13.lema

ve o muameledeki terakki zembereğinin hareketi mücahade ile olur

muamele-i kimyeviye

mesele insanın en kıymettar cihazı akıldır

mesela insanın en kıymettar cihazı akıldır

mesela insanın en kıymettar cihazı akıldır

eğer sırrı tevhid ile olsa o akıl hem ilahi kudsi defineleri

hem kainatın binler hazinelerini açan pırlanta gibi bir anahtarı olur

kainat kapıları zahiren açık görünse de batınen kapalıdır

nasıl sırrı tevhid ile olur aklım?

geçmişten elem gelecekten endişem varsa aklımı doğru kullanmıyor muyum?

aklımın kapasitesi nedir? var mıdır? (hayalden geniş)

akıl bir anahtardır

açacağı sınırsız kapı vardır çünkü esma tecellisi nihayetsizdir

her kapıyı açabilir mi aklım?

okudukça anahtarın dişlerini mi ayarlamış oluyorum?

aklını bileylemek

Gün

Rabbüşşiraya göre gün başkadır

Allahın günden maksadını Allah bilir, tefsirlerde mevcuddur

Küre-i arzdan güneşe bakınca doğması ve batması tüm 5 vakit

fecr-i kazib fecr-i sadık

tarihçe-i hayatta misali var

24 altın

sermaye

küre-i arzın kendi ekseni etrafında tam bir turu

saat yusuf as maliye bakanı

takvim intizam ızgara hendese calendar

Şükür

Rasulullah asm şükrünü secde ile ederdi. secde kulun rabbine en yakın olduğu andır. insan acz ve fakrını bilmekle insan olur

hattı Kur’an lemalar mecmuasından 23. lemada burayı okudum başımı kaldırdım ki gözüme MUHAMMED ASM lafzı ilişti, odamdaki duvarda asılıdır.

fani şahısların timsalleri ile oyalanmak fotoğraf vs hem zaten namahrem ise surete bakılmamalıdır. harama nazar edilmemelidir ali himmet olanlar timsallerle meşgul olmak yerine davalarını omuzlarlar

Abdülkadir Geylani ks ana ve babası biri Hz Hasan diğeri Hz Hüseyin soyundan ve yaşları ilerlemişken evliya sultanı dünyaya teşrif ediyor ks daha doğuşunda birinci kerameti gösteriyor ramazan ayında bebek olduğu halde annesinden süt emmiyor hatta havanın kapalı olması hasebiyle ramazan hilali tam çıkaramayan soruyor Abdulkadir geylaninin annesine süt emiyor mu diye o gün süt emmemiş annesi de niyetlenmiş halk da bunu duyunca niyetleniyor.

gençliğinde belki çocukluk ineğinden ses işitiyor sen bunun için yaratılmadın giderken kabe görüntüsü görüyor anneciğine söylüyor annesi firak vaktinin geldiğini anlıyor ona 40 altın verip sakın yalan söylemeyeceksin diye tembih ederek yolcu ediyor.

ilim öğrenmek ilim almak ilim talebesi olmak başlı başına bir iştir cehd ve gayret ister

muhakematı anlayana üstad 30 reşadiye altını vereceğim demiş

nurla meşguliyet maişette suhulete sebep olur

evliya sultanı Abdulkadirin himmetin eksiltme bizden ilahi

sünneti bilme, yaşa

yün yorgan yün kumaş yün giyinmek sünnettir. avrupada ağrı kesici olarak yün sarıyorlar hasta yataklarını yün yapıyorlar (koyun selahattin)

Nasıl bu nimete vasıl oldun?

ne ile müstehak oldun?

ve şükründe bulundun mu?

diye suale çekileceksin

insan azizdir

paşabahçe 59022 oval borcam kapaklı tencere 2000 cc

karahan organik un firması

tecrübe

Şükrün mikyası kanaattir ve iktisaddır ve rızadır ve memnuniyettir

şükürsüzlüğün mizanı hırstır ve israftır ve hürmetsizliktir, haram helal demeyip rast geleni yemektir.

karınca hırs ayaklar altında(hayatı içtimaiye mübarek)

arı kanaat baş üstünde, bal verir, ilhama mazfardır

rızkı nimeti istihfaf etmemek hafife almamak lazım

şükredersiniz nimetimi artırırım

Risale-i Nur’u bir sene kabul ederek ve anlayarak okuyan asrın hakikatli bir alimi olur

Allah bilinmek istedi, kul bilmek istiyor

bilme isteği meraktır, merak müşteri olmaktır, müşteri olmak soru sormaktır bunu asar-ı bediyeden çıkardım

müşteri para verir hakikat müşterisi merak ve ilgi verir

merak vasatta kullanılsa ilmin hocası

hiç olmazsa tefrit

ifrat olursa evham

meraki yönlendirmezsen psikolojik hastalık olur

lüzumsuz merak eden hasta!

kabullerimiz olmadan düşünemeyiz çünkü nazarımız sınırlı kıble de budur ön kabuller de budur

bilgi depolamamız lazım bilgisiz neticeye gitmek tehlikelidir der sherlock holmes

üstad işaratül icazda önce maddeler verir sonra der bunları koynuna koy gel hakikate girişeceğiz

bin parçalı koca bir puzzle önünde olsa bildiklerini anladıklarını koyarsın adım adım diğerleri de anlaşılır olur diğerleri görünmeye başlar kabuller olmalı ancak doğru kabuller

bize empoze edilmiş yanlış kabulleri mizanlara burmalıyız

her ne ise

kabul ederek ve anlayarak okumak işte

batının kokmuş sömürgeleştirmesinden yani sen düşünme bırak ben düşünürümünden kurtul onların standartlarıyla bunları kavrayamazsın

animasyon kahramanları çizgi film kahramanları küçük mermilerdir