İonic 2 Kurulumu / Kullanımı

ionic2angular2angularjs

7 yıl önce 11 yorum

Merhaba, bu makalede ionic 2 de bir mobil uygulaması yapılacaktır. Öncelikle şunu belirtmek istiyorum. Bu makale olduğu gibi Ganga Chris in yazdığı makalenin türkçe çevrisidir. Bir art niyetim yok. Görüntülenme alma gibi bir amacım da yok. Sadece İonic 1 den İonic 2 ye geçecek arkadaşlar için yardımı olur diye yapıyorum. Makalede benim kattığım bir şey yok, elimden geldiği kadar türkçeleştirmeye çalıştım. İyi dersler...

Angular 2 ve Ionic 2’de Uygulama Derlemek

Github apisini kullanarak ionic 2 de basit bir uygulama yapmaya başlarken (bu makale Ionic 2 RC.0 Release için güncellenmiştir.)

Ionic Framework HTML, CSS ve JavaScript (Angular) üzerinden hibrit uygulama gelşitirmenizi sağlar. Ionic 1 Angular 1.* ile derlenmiş ve yakın zamanda Angular 2 ile ürüne çıkmıştır, Major (Önemli) güncelleme de yakında gelecektir.

Ionic 2 şu anda Ürün Adayı, Hızlıca hibrit uygulama geliştirmek istiyorsanız, Angular 2 ve javascript biliyorsanız, bu klavuz sizi hızlandıracaktır.

Neden İonic 2 Kullanmalıyız ?

HTML/CSS/JS biliyorsanız

Zaten bunları bildiğiniz için HTML, JavaScript ve CSS ile hibrit uygulama geliştirebilirsiniz. Angular 2 ile çalışırsanız, sorunsuz şekilde geçiş yaparsınız.

Aşamalı Web uygulamaları geliştirmek avantajlı

Google Aşamalı Web Uygulamaları hakkında konuşmuş. Basit olarak, web uygulamaları bize buna benzer uygulamaları deneyim kazandırıyor. Web teknolojileri kullanılmış İonic 2 bu safta.

Aslında son Angular Connect konferansında, ionic ekibinin bazı üyeleri  Aşamalı Web Uygulamaları hakkında konuştu.

İonic 2 ile yapılan örnek aşamalı web uygulamaları pwa.ionic.io da mevcut. Telefonunuzdan chrome tarayıcısı ile herhangi bir uygulamayı ziyaret etmeniz yeterli. Menüye tıklayın ve Anasayfaya ekle'yi seçin. Ardından giriş sayfasında yüklü olacak.

Büyük mobil platformları hedefliyor

En önemli platformlarda (Android, iOS ve Windows Phone) geliştirme yapmak istiyorsanız, bir codebase (kod tabanına) e sahip olmanız durumu hızlandıracaktır ve ionic böyle bir senaryo için mükemmeldir. Uygulamayı güncellemek bir codebase’i düzenlemek kadar kolaydır.

Native işlevselliği uygulamayı kolaylaştırır

Uygulamanıza eklemek istediğiniz native fonksiyonlar’ı kolaylaştıran birçok Cordova eklentisi mevcut. İonic projenizde kullanacağınız cordova eklentilerini kullanmanıza olanak sağlar. İonic dokümantasyonunda bazı örnek eklentiler vardır.

Neler Yapacağız

Github’ın apisini kullanan bir uygulama yapacağız. Uygulama github kullanıcılarını listeleyecek, kullanıcıları arayacağımızı bir arama kutusu olacak ve onların takipçi sayılarını, repository’lerini ve haklarını görebileceğiz. Uygulamanın bitmiş hali kısa bir videoda var.

İonic 2 Kurulumu

İonic 2  HTML, CSS ve JavaScript ile hibrit uygulama geliştirmek için Cordova üzerine inşa edilmiştir. Nodejs in kurulu olduğundan emin olun.

Cordova’yı kurun.

 

npm install -g cordova

 

Mac/Linux/Unix kullanıcıları eğer EACCESS hatası alırsanız, sudo ile çalıştırmayı deneyin veya izinleri yönetin.

İonic’i kurun

 

npm install -g ionic

 

Not: Eğer anlamadığınız bir hata ile karşılaşırsanız npm uninstall -g ionic diyerek ionic’i kaldırın, npm cache clean ile cache i temizleyin. Sonra tekrar npm install -g ionic diyerek kurun.

Bu Ionic CLI yı iş istasyonunuza yükler ve ionic artık hazır.

NOT: kurulan ionic detaylarını görmek için

 

ionic info

 

Neredeyse aşağıdaki gibi sonuçlar görmeniz gerekir.

Ionic CLI Version: 2.1.13
Ionic App Lib Version: 2.1.7
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Linux 4.8
Node Version: v6.9.2
Xcode version: Not installed

Şu anki uyarıları yok sayabilirsiniz. Çoğu, android ya da ios a dağıtmak istediğinizde gereklidir.

Son olarak Typescript bulundurmanız gerekli. Typescript javascript’in bir üst sınıfıdır ve Angular 2 de gerçekten iyi çalışır. Bir yazarın yazdığı makaleyi uygulayarak typescript ile hızlanabilirsiniz.

 

npm install -g typescript

 

Merhaba Ionic 2

Ionic 2 basit hızlıca uygulama geliştirmek ve şekillendirmek için başlangıç sablonu sunar. Uygulamamız githubIonic olacak ve böylece ionic 2 ile hızlıca iskele edeceğiz.

Uçbiriminize

ionic start githubIonic tutorial –v2

Yukarıdaki komut projenize ionic öğretici şablonunu ekler. Daha sonra npm paketlerini yükleyin (npm install ile). Uygulamamızı Typescript kullanarak oluşturacağız bu yüzden --ts bayrağımız var. cd ile  githubIonic dizinine geçin cd githubIonic. Önce uygulamayı servis edip, daha sonra klasör yapısına geçeceğiz. Şu komutu çalıştırın.

ionic serve

Uygulamanızı nasıl servis etmeniz geretiği sorulabilir localhost:8100 i seçin. Sonra localhost:8100 i açın. Şuna benzer bir şey görülmelidir.

Chrome Dev Araçlarım'ı açtığımda, sol üst kısımda cihaz simgesini tıkladığımı ve uygulamanın bir cihaz ekranında gösterildiğine dikkat edin. Galaxy S5 yazıyor.

Uygulamayı tüm platformda görmek isteyebilirsiniz. Bu durumda şunu çalıştırın.

ionic serve -l

Tarayıcınızda açılmazsa http://localhost:8100/ionic-lab linkine girin.

Uygulamayla uğraşabilirsiniz.

İonic 2 Proje Yapısı

İonic 2 proje oluşturduğunuzda şu yapı ile karşılaşırsınız

├── config.xml
├── hooks
├── ionic.config.json
├── node_modules
├── package.json
├── platforms
├── plugins
├── resources
├── src
├── tsconfig.json
├── tslint.json

Hemen hemen src klasöründe işin %90 ını harcayacağız, çünkü uygulamanın mantığı buraya kurulu. Ancak uygulama basit olarak src/index.html den başlar. Derleme sırasında www klasöründe kopyalanır.

src/index.html


<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="UTF-8">
  <title>Ionic App</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale= maximum-scale=1.0, user-scalable=no">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">
 
  <link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
  <link rel="manifest" href="assets/manifest.json">
  <meta name="theme-color" content="#4e8ef7">
 
  <!-- un-comment this code to enable service worker
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('assets/service-worker.js')
        .then(() => console.log('service worker installed'))
        .catch(err => console.log('Error', err));
    }
  </script>-->
 
  <link href="build/main.css" rel="stylesheet">
 
</head>
<body>
 
  <!-- Ionic's root component and where the app will load -->
  <ion-app></ion-app>
 
  <!-- cordova.js required for cordova apps -->
  <script src="cordova.js"></script>
 
  <!-- The polyfills js is generated during the build process -->
  <script src="build/polyfills.js"></script>
 
  <!-- The bundle js is generated during the build process -->
  <script src="build/main.js"></script>
 
</body>
</html>

Bu dosya üzerinde hiçbir işlem yapmayacağız. <ion-app></ion-app> dikkat edin: Burası uygulamanın giriş noktası. Buna uygulamanın kök bileşeni deniyor. Nerede tanımlanacağının kısaca göreceğiz. Ancak angular 2 uygulamaları bu şekilde oluşturuldu. index.html dosyasında daima <root-component></root-component> vardır. Bu dosya genellikle ionic bağımlı dosyalarını yüklüyor. İlginç bir şey de  index.html dosyasındaki yorumlanmış script tagı. Service Workers bu makalenin dışındadır ama web uygulamaları söz konusu olduğunda çevrimdışı yeteneklerini etkinleştirirler ve aşamalı web uygulamaları geliştirirken iyi olur.

Kısaca diğer proje yapısından bahsedeceğim.

  • config.xml – Bu, uygulamanızı gerçek bir cihaza yüklemek için kullanılacak uygulama adı ve paket adı gibi yapılandırmaları içerir. 

  • Src - Burası, uygulamanızı oluşturma zamanımızın çoğunu harcayacağımız yerdir. Uygulamamızın yapılandırılmış kaynak kodunu içerir. 

  • node_modules - package.json dosyasında listelenen npm paketlerini içerir. Bunlar, ionic uygulamasını oluşturmak için gerekli olan paketlerdir. 

  • platforms - Burada platforma özel yapılar, yapı araçları ve paketler / kütüphaneler saklanır. Bulunduğunuz platform için bir klasör oluşturacaktır. Örneğin bir android platformu eklemek için, basitçe ionic platform android'i çalıştırın ve bu android klasörünü bu klasöre ekleyecektir. 

  • plugins - Cordova eklentileri yüklendiğinizde burada saklanacaktır. Cordova eklentileri, uygulamanızın mobil cihazda native fonksiyonlara sahip olmasını sağlar (ör. Cihazın medya saklama alanına erişme veya bluetooth API'si). 

  • resources - Uygulamanızın iconların ve açılış ekranı resimlerini barındırır. 

src/app/app.component.ts, uygulamanızın kök bileşenidir. Yüklemeler ve tanımlamalar src/app/app.component.ts içindedir, basitce uygulamanızı bir modül olarak temsil eder, app/main.dev.ts veya app/main.prod.ts tanımlamaya bağlı olarak yüklenir. Bu yapı [Derlemeden önce] desteklenir, bu Angular 2 de derlemeyi uygulama paketinden çıkaran özelliktir.

src/app/app.html dosyası uygulamanın kök görünümüdür. Bu görünümde bir side menu (yan menü ) var.

Angular 2 ye aşina iseniz, bu öngörülebilir, değilseniz devam ederken bu yapının bazı temellerinide ele alacağız

İonic 2 genellikle src/pages dizinine bölünür. Belirli bir zamanda ekranda hangi sayfa görünümü bulunduğunu düşünebilirsiniz (Android geliştiricilerin etkinliği gibi.). Kavram aslında ilginç, çünkü  ionic 2 de sayfalar birbirinin üstüne yığılmış halde bulunur, geri gelindiğinde yığının en üst sayfasını kaldırmak kadar basittir. Last in First Out (Son giren ilk çıkar).

src/themes klasöründe ise uygulamanın temasında bize yardımcı olan sass dosyaları bulunur.

Son olarak src/app/app.module.ts dosyasına bir göz atalım


import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HelloIonicPage } from '../pages/hello-ionic/hello-ionic';
import { ItemDetailsPage } from '../pages/item-details/item-details';
import { ListPage } from '../pages/list/list';

@NgModule({
  declarations: [
    MyApp,
    HelloIonicPage,
    ItemDetailsPage,
    ListPage
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HelloIonicPage,
    ItemDetailsPage,
    ListPage
  ],
  providers: []
})
export class AppModule {}

Angular 2 modül yapısını kullandığımız için, tüm component, providers, pipes önceden bildirmek zorundayız. Bunları gittikçe bu dosyaya ekleyeceğiz. Bu şablonun gerektirdiği tüm sayfaları içe aktardığını, @NgModule'nin declarations (tanımlamalar) özelliğine ve ayrıca entryComponents (girdi bileşenler) özelliğine eklediğini görebilirsiniz. Burada ayrıca, src/app/app.component.ts dosyasında tanımlanan kök bileşenimizi içe aktarırız.

Basit Uygulamamızın Yapısı

Ionic 2 CLI tarafında canlı yükleme yapıyoruz.

ionic serve

Ionic uygulamamızın 3 tane anasayfası var. Biri github kullanıcıları için, biri organizasyonlar için diğeride repositoryler için. Son iki sayfa sol menüde görünecektir, onlar herhangi bir içerikleri olmayacak. Kullanıcı sayfası kullanıcının ayrıntılarını görmenizi sağlayacaktır. src/pages  klasöründe bulunan tüm dosyaları silin. Bu 3 yapıyı oluşturmak Ionic 2 ile çabucak oluşturağız.

ionic g page users

ionic g page repos

ionic g page organisations

Bu isimlerle toplamda 3 klasör oluşacaktır. Burdaki g generate in kısaltmasıdır ionic generate page sayfaIsmi şekilde de yapabilirsiniz. Klasörlere girin ve tüm html dosyalarını bunlarla değiştirin.

src/pages/users/users.html


<ion-header>
  <ion-navbar>
    <button ion-button icon-only menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>
      Users
    </ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  <h3>Users view page</h3>
</ion-content>

src/pages/repos/repos.html


<ion-header>
  <ion-navbar>
    <button ion-button icon-only menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>
      Repos
    </ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  <h3>Repos view page</h3>
</ion-content>

src/pages/organisations/organizations.html


<ion-header>
  <ion-navbar>
    <button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Organisations</ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
 
  <h3>Organizations view page</h3>
 
</ion-content>

Ionic 2 yanında bazı bileşenlerle gelir.

<ion-navbar> responsive bir navigasyon bardır. Navigasyon bileşeni diyebiliriz.

ion-button Ionic 2 ye ait bir button directive.

ion-button Ionic 2 ye ait bir directive. Bu butonun icon olduğunu belirtilecekse ion-only directive kullanılır.

menuToggle sol menüyü değiştiren bir directive.

<ion-icon> ise iconları yönetimiyle sorumlu. Buna sadece ionic icon listesinde bulunan isimleri ekleyin.

<ion-title> sayfa başlığını görüntüler.

<ion-content> sayfanın içeriğini barındırır. padding ise sayfaya kenar iç boşluğu verir.

Bunları sayfa olarak düşündüğümüz için class adlarını bir sayfa sonekine sahip olacak şekilde değiştirmek güzel olurdu.

Tüm typescript dosyalarını şunlarla güncelleyin.

src/pages/users.ts


import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-users',
  templateUrl: 'users.html'
})

export class UsersPage {

  constructor(public navCtrl: NavController) {}

  ionViewDidLoad() {
    console.log('Hello Users Page');
  }
}

src/pages/repos.ts


import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-repos',
  templateUrl: 'repos.html'
})
export class ReposPage {

  constructor(public navCtrl: NavController) {}

  ionViewDidLoad() {
    console.log('Hello Repos Page');
  }
}

src/pages/organisations.ts


import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-organizations',
  templateUrl: 'organisations.html'
})
export class OrganisationsPage {

  constructor(public navCtrl: NavController) {}
 
  ionViewDidLoad() {
    console.log('Hello Organisations Page');
  }
}

ionViewDidLoad methodu ionic yaşam döngüsüdür. Sayfa tetiklenip yüklenince çalışır. Sezgizel değil mi ?

Ardından bu sayfaları sol tarafa ekleyeceğiz. src/app/app.component.ts dosyasına gidip birkaç düzenleme yapacağız. Farkındaysanız pages adı verilen class property ‘si çağrılmış. src/app/app.html dosyasında gösterildiği gibi sidenav (ion-menu) oluşturan şey budur.


<ion-menu [content]="content">
 
  <ion-header>
    <ion-toolbar>
      <ion-title>Pages</ion-title>
    </ion-toolbar>
  </ion-header>
 
  <ion-content>
    <ion-list>
      <button ion-item *ngFor="let p of pages" (click)="openPage(p)">
        {{p.title}}
      </button>
    </ion-list>
  </ion-content>
 
</ion-menu>
 
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>

Bu dosyayı üretildiği şekilde bırakın. Burdaki butonlar *ngFor="let p of pages" directive ‘ine bağlıdır, Angularjs 2 de yenilenen taglar bu şekildedir. Sadece sayfa tümünce her öğe için yeniden şablon oluşturur. Pages property değişirse sidenav (ion-menu) içeriğini değiştiririz.<ion-nav> gezinilen sayfanın göründüğü yerdir. root property si rootPage sınıfına bağlıdır. Tanımını biraz sonra göreceğiz.

Gerekli sayfaları sidenav a eklemek için src/app/app.component.ts dosyasını değiştireceğiz. Silinen sayfalar için; üstte iki import ifadesi (HelloIonicPage ve ListPage) silindi ve oluşturduğumuz sayfalar için import ifadeleri ekledim.

src/app/app.component.ts


import { Component, ViewChild } from '@angular/core';

import { Platform, MenuController, Nav } from 'ionic-angular';

import { StatusBar } from 'ionic-native';

import { UsersPage } from '../pages/users/users';
import { ReposPage } from '../pages/repos/repos';
import { OrganisationsPage } from '../pages/organisations/organisations';

@Component({
  templateUrl: 'app.html'
})

export class MyApp {
  // Kısaltmak için yorum yapıldı, aynısı.
}

UsersPage, ReposPage ve OrganisationsPage, tek tek sayfaları oluşturduğumuzda iskele yapılan sayfaları temsil eden bileşen classlarıdır. src/pages/users/users.ts dosyasını, src/pages/repos/repos.ts dosyasını ve src/pages/organisations/organisations.ts dosyasını kontrol edebilirsiniz.

Ardından pages property sini yeni sayfamıza uyacak şekilde düzenliyoruz.

src/app/app.component.ts


// importlar kısa olsun diye yorumlandı

export class MyApp {

 @ViewChild(Nav) nav: Nav;

  // UsersPage, root (veya birinci) sayfa tanımlanıyor
  rootPage: any = UsersPage;
  pages: Array<{title: string, component: any}>;

  constructor(public platform: Platform,  public menu: MenuController) {
    this.initializeApp();
 
    // diğer sayfalar
    this.pages = [
      { title: 'Users', component: UsersPage },
      { title: 'Repos', component: ReposPage },
      { title: 'Organisations', component: OrganisationsPage },      
    ];
  }

  initializeApp() {
    this.platform.ready().then(() => {
      // Tamam, şimdi platform hazır ve pluginde mevcut.
      // Burada ihtiyaç duyabileceğiniz daha üst seviye native fonksiyonlar çalıştırabilirsiniz.

      StatusBar.styleDefault();
    });
  }

  openPage(page) {
    // menuden bir bağlantıya tıklanınca menüyü kapat
    this.menu.close();
    // şuan geçerli sayfa değilse yeni sayfaya git
    this.nav.setRoot(page.component);
  }

}

RootPage class propertysinin UsersPage olarak ayarlandığına dikkat edin. src/app/app.html görünümünde <ion-nav> root property bu rootPage'e bağlı olduğunu hatırlayın. Bu uygulama yüklenirken ilk açılacak sayfanın UsersPage olacağı anlamına geliyor.

Buna uygun olarak constructor içinde this.page değerini değiştirdik.

openPage methodu sayfaları açmakla sorumludur. src/app/app.html dosyasına bakarsanız, sayfa listesinde bu methodu (click)="openPage(p)" şeklinde görebilirsiniz. Bir sayfayı alır ve açar. Gayet basit, sizce ?

Bu kurulumu tamamlamak için yapmamız gereken son şey, sayfalarımız hakkında açısal bilgi vermektir. Bu src/app/app.module.ts dosyasında yapılır.

Üç sayfayı da içe aktarın ve bunları @NgModule öğesine bildirin ve entryComponents özelliklerine ekleyin. Kullanılmayan import ları silin.

src/app/app.module.ts


import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';

import { UsersPage } from '../pages/users/users';
import { ReposPage } from '../pages/repos/repos';
import { OrganisationsPage } from '../pages/organisations/organisations';

@NgModule({
  declarations: [
    MyApp,
    UsersPage,
    ReposPage,
    OrganisationsPage
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    UsersPage,
    ReposPage,
    OrganisationsPage
  ],
  providers: []
})
export class AppModule {}

Sonra uygulamayı terminalden çalıştırın ve http://localhost:8100 adresini açın

Github Kullanıcılarını Getirelim

Github kullanıcılarını https://api.github.com/users adresinden almak için bir service oluşturacağız. Api json formatında github kullanıcılarının yaklaşık ilk 30'unu listeliyor.

Öncelikle bir Github kullanıcı modeli oluşturmamız gerekiyor. Bu sınıf github kullanıcısı için istediğimiz ilgili alanları tutar, zira github bundan daha fazla ayrıntı sunar.

Src dizininine model diye bir dizin oluşturuyoruz. Bu dizin daha sonraları oluşturacağımız modelleri ve şimdi oluşturacağımız user modelini saklayacağımız yer olacak. src/models altına user.ts diye dosya oluşturun.

src/models/user.ts


// Github apisine dayanan User model
// https://api.github.com/users/{username}
export interface User {
  login: string;
  avatar_url: string;
  public_repos: number;
  public_gists: number;
  followers: number;
  following: number;
}

Github apisinden dönen bizim kullanacağımız alanları ekledik. Modelimiz tanımlandığına göre, kullanıcıları github'dan çekmemizi sağlamak için bir github-users provider oluşturabiliriz. Providerı oluşturmak için, terminalinizde aşağıdaki komutu çalıştırın:

ionic g provider github-users

src dizininde provider adında bir klasör ve bir github-users.ts dosyası oluşturur.

Github kullanıcılarını eklemek için github-users.ts dosyasına bir method eklememiz gerekiyor.

Oluşturulan dosyayı şöyle değiştirelim.


import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';

import { User } from '../models/user';

@Injectable()
export class GithubUsers {
  githubApiUrl = 'https://api.github.com';

  constructor(public http: Http) { }

  // Tüm github kullanıcılarını yükle
  load(): Observable<User[]> {
    return this.http.get(`${this.githubApiUrl}/users`)
      .map(res => <User[]>res.json());
  }
}

@Injectable dekoratörü Angularjs 2 de tanımlanan services/providers olarak tanımlandığını bildirir.

Observable import gereklidir çünkü github API çağrısının geri dönen sonuçları gözlemlenebilir olarak döndürürüz. Gözlemlemeyi bir aboneymiş gibi, veri akışı olarak düşünebilirsiniz. Buna biraz daha detaylı olarak kısa süre içinde bakacağız.

Yaptığımız ilk iş user model i içe import etmekti import {User} from '../models/user'.

Sonra, load diye  fonksiyon oluşturduk ve geriye Observable dönüş yapabiliyor.

Github api'sine bir istekte bulunur ve json dönen yanıtı res.json() ile ayrıştırırız ardından bunu <User[]>res.json() ile dizi olarak atarız. Geriye gözlenmelenebilir döner, bu kullanıcıları görebilmek için abone olacağız.

Hizmetimizi tüm uygulamada kullanmak için, dosyayı src/app/app.module.ts dosyasına eklememiz gerekiyor.

src/app/app.module.ts dosyası.


// Importlar Kısa olsun diye yorumladı

import { GithubUsers } from '../providers/github-users';

@NgModule({
  declarations: [
    // Tanımlamalar kısa olsun diye yorumladı
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    // Giriş bileşenleri kısa olsun diye yorumladı
  ],
  providers: [GithubUsers] // GithubUsers provider ekleniyor
})
export class AppModule {}

Burda GithubUsers ları içeri aktardık ve NgModule'nin providers propertysine ekledik.

Github kullanıcılarını Görme

Artık kullanıcılarımız var ve bunları kullanıcı sayfasında görme zamanı geldi. Bunu yapmadan önce, providerların kullanıcı getirip getirmediğini bir test edelim.

src/pages/users/users.ts dosyasını şu şekile getirin.


import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

import { User } from '../../models/user';

import {  GithubUsers } from '../../providers/github-users';

@Component({
  selector: 'page-users',
  templateUrl: 'users.html'
})

export class UsersPage {
  users: User[]

  constructor(public navCtrl: NavController, private githubUsers: GithubUsers) {
    githubUsers.load().subscribe(users => {
      console.log(users)
    })
  }
}

Öncelikle GithubUsers Providerını yukarıda import (içeri dahil) import {GithubUsers} from '../../providers/github-users'; şeklinde ettik. Ayrıca User modelinide import ettik.

UsersPage constructor ında githubUsers: GithubUsers ekledik. Bu şekilde Angular 2 de tüm dependencies (bağımlılıkları) inject (enjekte) ettik. Daha sonra constructor method da çağrılan fonksiyon değerleri console.log ile konsola yazdırdık.

Bunları tamamladıktan sonra ionic serve ile çalıştırıp https://localhost:8100 konumuna giderek Chrome Dev Tools’u açıyoruz.

Birkaç nesnenin konsolumuza güncellendiğini görmelisiniz, ilk nesnesine bakarken kullanıcı modelimizin neredeyse tüm özellikleri bulunmaktadır.

User sayfasında kullancıları görmemiz için bir local değişkene ihtiyacımız var. Bu yüzden class’ımıza users: User[] diye tanımlıyoruz. Sayfada dönen değerleri bu değişkene atmamız gerekiyor.

src/pages/users/users.ts


// Importlar kısa olsun diye yorumlandı

@Component({
  // Component kısa olsun diye yorumlandı
})
export class UsersPage {
  users: User[]

  constructor(public navCtrl: NavController, private githubUsers: GithubUsers) {
    githubUsers.load().subscribe(users => {
      this.users = users;
    })
  }
}

Şimdi bunları görüntülememiz için html dosyasını düzenleyelim

src/pages/users/users.html


<ion-header>
  <!-- ion-header içerikleri kısa olsun diye yorumlandı -->
</ion-header>

<ion-content padding>
  <ion-list>
    <button ion-item *ngFor="let user of users">
      <ion-avatar item-left>
        <img [src]="user.avatar_url">
      </ion-avatar>
      <h2>{{ user.login }}</h2>
      <ion-icon name="arrow-forward" item-right></ion-icon>
    </button>
  </ion-list>
</ion-content>

ion-list ionicte içerik listeleri oluşturmanızı sağlar.

ion-item directive i ise *ngFor directive ile döngüye sokulmasını sağlar. *ngFor="let user of users" ile tüm kullanıcıları dönüyoruz. users burada UsersPage sınıfında bulunan property users ı temsil eder.

Ardından avatar için bind işlemi yaparak ion-avatar directive’inde belirtiyoruz, bu sadece kenarları yuvarlak yapar. Hatırlayın kullanıcının avatar_url diye özelliği vardı, o yüzden user.avatar_url.

Ardından kullanıcının github username alanını ekleriz. {{user.login}}

ion-icon ionic ikonları eklemek için kullanılır. Kullanmak istediğiniz simgenin adını verin. Ben şunu şeçtim arrow-forward

item-right directive ise ikonu en sağa getirir.

Projenizi terminale ionic serve yazarak çalıştırın ve http://localhost:8100 linkine gidin. Şunun gibi olmalıdır.

Kullanıcı Detaylarını Görme

Ardından, kullanıcılar listesindeki herhangi bir kullanıcıya tıklayarak o kullanıcı için ayrıntılar view ‘ı oluşturacağız.

Ionic 2 CLI kullanarak user-details sayfası oluşturun.

ionic g page user-details

user-details dizini pages dizini içine oluşturulur ve buna ait html, ts ve stil için scss olmak üzere üç dosya bulunur.

src/app/pages/user-details/user-details.ts içindeki class ismini UserDetailsPage diye değiştirin, bu gerekli değil sadece bir tercih.


import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-user-details',
  templateUrl: 'user-details.html'
})
export class UserDetailsPage {
  constructor(public navCtrl: NavController) {}

  ionViewDidLoad() {
    console.log('Hello UserDetails Page');
  }
}

Herhangi bir şey yapmadan önce kullanıcı listesinde birine tıklayınca çalışıp çalışmadığından emin olmamız gerekir.

İlk olarak src/app/app.module.ts dosyasına ekliyoruz.


// Diğer importlar

import {UserDetailsPage } from '../pages/user-details/user-details';

@NgModule({
  declarations: [
    // Diğer Pages,
    UserDetailsPage // Buraya UserDetailsPage ekliyoruz
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    // Diğer Pages,
    UserDetailsPage // Buraya UserDetailsPage ekliyoruz
  ],
  providers: [GithubUsers]
})
export class AppModule {}

Sonrasında user-details sayfasında birkaç değişiklik yapalım.

src/pages/user-details/user-details.html


<ion-header>
  <ion-navbar>
    <ion-title>{{login}}'s details</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding >
  <h3>User Details view page</h3>
</ion-content>

Kullanıcıyı bu view da geçirmeyi planladığımız için, görünüm başlığına {{login}} ekledik.

Sonra user sayfasında gidip user details yönlendirmesi yapacağız.

src/pages/users/users.ts


// Diğer Importlar

import { UserDetailsPage } from '../user-details/user-details';

@Component({
  selector: 'page-users',
  templateUrl: 'users.html'
})
export class UsersPage {
  users: User[]

  constructor(public navCtrl: NavController, private githubUsers: GithubUsers) {
    // Kısa olsun diye yorumlandı
  }
 
  goToDetails(login: string) {
    this.navCtrl.push(UserDetailsPage, {login});
  }
}

Öncelikle UserDetailsPage üstte import {UserDetailsPage} from '../user-details/user-details' şeklinde import ettik.

Ardından navigation için goToDetails methodu ekledik. Birde login diye (username) parametresi var.

Ionic 2 navigation bir yığın olarak ele alınır, yeni eklenecek sayfaların birbirilerinin üstüne ekleneceği anlamına gelir. Bu yüzden görüldüğü üzere this.navCtrl.push diyerek içine attık. Geriye dönmek veya geri düğmesine basmak, yığının son öğesini açmaya benzer (Son Giren İlk Çıkar). Push’un 2. parametresi sayfaya belirtmek istediğiniz nesnedir.

{login} ise es2015 property kısaltması. Es5 burda {login: login} anlamına gelir.

Son olarak goToDetails i view da çağıracağız.

src/pages/users/users.html


<!-- ion-header -->
<ion-content padding>
  <ion-list>
    <button ion-item *ngFor="let user of users" (click)="goToDetails(user.login)">
      <!-- ion-item content-->
    </button>
  </ion-list>
</ion-content>

Yaptığımız tek şey *ngFor directive ine (click)="goToDetails(user.login)" eklemek oldu.

Son olarak kullanıcı detayları sayfasına yönlendirme yapmamız gerek.

src/pages/user-details/user-details.ts


import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';

@Component({
  selector: 'page-user-details',
  templateUrl: 'user-details.html'
})
export class UserDetailsPage {
  login: string;

  constructor(public navCtrl: NavController, private navParams: NavParams) {
    this.login = navParams.get('login');
  }
}

navigation parametrelerine erişmemizi sağlamak için yalnızca mevcut importlara NavParams ekledik.

login property tipi string tanımladım. Unutmayın ki bu username i temsil eder.

NavParams provider ını navParams olarak constructor a inject ederiz, daha sonra bu değeri getirmek  ve önceki sayfadaki parametrenin değerini elde etmek için this.login = navParams.get ('login') kullanıyoruz.

http://localhost:8100 adresine gidip bir kullanıcıya tıklayıp bunu görmelisiniz.

Tıklanan kullanıcının adını title olarak görmelisiniz. (ör: mojombo details)

Gerçekten Kullanıcı Detayları Getirelim

Artık ayrıntıları ve içeriğiyle kullanıcıya sahibiz, onun ayrıntılarını bulmamız gerekiyor. İstekler için GithubUsers provider ı düzenlememiz gerekiyor. Request https://api.github.com/users/{login} adresine yapılacak, burada son parametre kullanıcı adı olacak.

src/providers/github-users.ts


// Importlar
@Injectable()
export class GithubUsers {
  githubApiUrl = 'https://api.github.com';

  constructor(public http: Http) { }

  // Tüm github kullanıcıları yükle
  load(): Observable<User[]> {
    // yükle
  }

  // o kullanıcının detaylarını yükle
  loadDetails(login: string): Observable<User> {
    return this.http.get(`${this.githubApiUrl}/users/${login}`)
      .map(res => <User>(res.json()));
  }
}

ilk load fonksiyonuna nerdeyse benzer loadDetails() diye bir fonksiyon ekledik. Bu login parametresine bağlı olarak geriye Observable User tipinde değer dönderir, abone olduğumuzda isteğin sonuçlarını almak için. Dönen değeri <User>res.json() ile parçalarız.

http.get request i ${this.githubApiUrl}/users/${login} adresine atar. Bu ES6 şablon dizeleri typescript de mevcut. Kaçış karakteri yani (`)  ile ${var} şeklide kullanırsak içinde bulunan string’i bir dizeye dönüştürür.

Şimdi user-details sayfasına gidiyoruz ve doğru verileri işliyoruz.

src/pages/user-details/user-details.ts


// Diğer importlar

import { User } from '../../models/user';

import { GithubUsers } from '../../providers/github-users';

@Component({
  selector: 'page-user-details',
  templateUrl: 'user-details.html'
})
export class UserDetailsPage {
  user: User;
  login: string;

  constructor(public navCtrl: NavController, private navParams: NavParams, private githubUsers: GithubUsers) {
    this.login = navParams.get('login');
    githubUsers.loadDetails(this.login).subscribe(user => {
      this.user = user;
      console.log(user)
    })
  }
}

Öncelikle GithubUsers üste import {GithubUsers} from '../../providers/github-users' şeklinde import ettik.

Aynı şeklide User modelide import {User} from '../../models/user';

Ardından constructor e githubUsers inject edip githubUsers.loadDetails değerini navigation params a login diyerek attık. Results de dönen değeride hata yakalama amaçlı konsola yazdırdık.

http://localhost:8100 adresinde gidin ve bir kullanıcıyı seçin.

Log a basılan object i açarsanız o kullanıcıya ait bilgileri görebilirsiniz.

Kullanıcı Detaylarını Ekranda Görme

Artık kullanıcının ayrıntıları elimizde ve bunları ekranda göstermeliyiz. Yalnızca followers, following, açık repolarını ve açık gist numaralarını görüntüleneceğiz.

console.log komutunu user-detail.ts dosyasından kaldıralım.

Sonuç, this.user = user diyerek dönen değeri class ın property sine attık ve artık bunu html dosyasında görmenin zamanı geldi.

app/pages/user-details/user-details.html


<!-- ion-header -->

<ion-content padding >
  <ion-list>
    <ion-item>
      <ion-label>Followers</ion-label>
      <ion-badge item-right>{{user?.followers}}</ion-badge>
    </ion-item>
     <ion-item>
      <ion-label>Following</ion-label>
      <ion-badge item-right>{{user?.following}}</ion-badge>
    </ion-item>
     <ion-item>
      <ion-label>Repos</ion-label>
      <ion-badge item-right>{{user?.public_repos}}</ion-badge>
    </ion-item>
     <ion-item>
      <ion-label>Gists</ion-label>
      <ion-badge item-right>{{user?.public_gists}}</ion-badge>
    </ion-item>
  </ion-list>    
</ion-content>

Burada user?.property şeklindeki tanımlamalar users değerinde null ifadeler olabileceğini ifade ederek bir sorun çıkmamasını sağlar.

Kullanıcı değerlerini görmek için ion-badge ve ion-label kullandık. http://localhost:8100 adresine gidin ve bir kullanıcı seçin.

Kullanıcı Arama

Kullanıcı sayfasının üst tarafına Ionic 2 e ait bir arama kutusu ekleyeceğiz. Ionic 2 bize component de searchbar sağlar.

src/pages/users/users.html


<!-- header kısa olsun diye yorumlandı-->

<ion-content padding>
  <ion-searchbar></ion-searchbar>
  <ion-list>
    <!--burasıda kısa olsun diye yorumlandı-->
  </ion-list>
</ion-content>

üst tarafa <ion-searchbar> ekledik birisini aramak için bize gerekiyor.

Aslında hali hazırda bir datamız olduğunda arama yapmamız kolaylaşacak ama olmayan kişiler geleceği zaman api kullanmamız gerekiyor. Böylelikle gelen kullanıcıları update edeceğiz. Api olarak  https://api.github.com/search/users?q={searchParam}, arama parametresi olarak searchParam

GithubUsers provider ına arama yapmak için method ekleyeceğiz. load methoduna benziyor.

src/providers/github-users.ts


// Importlar
@Injectable()
export class GithubUsers {
  githubApiUrl = 'https://api.github.com';

  constructor(public http: Http) { }

  // Tüm github kullanıcıları yükle
  load(): Observable<User[]> {
    // kullanıcıları yükle
  }

  // o kullanıcının detaylarını yükle
  loadDetails(login: string): Observable<User> {
    // ayrıntıları yükle
  }

  // Github kullanıcılarında arama yapma  
  searchUsers(searchParam: string): Observable<User[]> {
    return this.http.get(`${this.githubApiUrl}/search/users?q=${searchParam}`)
      .map(res => <User[]>(res.json().items))
  }
}

searchUsers methodu, bir api url'sine iletilecek bir arama parametresi alır. Daha sonra, başlangıçta load yöntemi için yaptığımız gibi Observable türünde User [] (Kullanıcı dizisi) döndürürüz.

Arama methodunu test etmek için, kullanıcılar sayfasına gidin.

src/pages/users/users.ts


// Importlar

@Component({
  selector: 'page-users',
  templateUrl: 'users.html'
})
export class UsersPage {
  users: User[]

  constructor(public navCtrl: NavController, private githubUsers: GithubUsers) {
    // Github users yükle

    githubUsers
      .searchUsers('scotch').subscribe(users => {
        console.log(users)
      });
  }
  // goToDetails
}

constructor da bulunan githubUsers.searchUsers('scotch') request atmalı ve geriye değer döndermelidir. http://localhost:8100 açıp bakın.

Kırmızı ile belirtilen yerlerin her ikisinde de scotch var.

Basit bir arama

3 veya daha fazla karakter girildiğinde arama yapacağız. Kullanıcıdan girilen değeri arama çubuğundan alalım.

src/pages/users/user.html


<!-- HTML kısalık için yorumlandı -->

<ion-content padding >
  <ion-searchbar (input)="search($event)"></ion-searchbar>
  <ion-list>
    <!-- HTML kısalık için yorumlandı -->
  </ion-list>
</ion-content>

Buradaki (input)="search($event)" directive ion-searchbar a ait bir her input eventı için çalışır durumda.

src/pages/users/users.ts


// Importlar
@Component({
  selector: 'page-users',
  templateUrl: 'users.html'
})
export class UsersPage {
  users: User[]
  originalUsers: User[];

  constructor(public navCtrl: NavController, private githubUsers: GithubUsers) {
    githubUsers.load().subscribe(users => {
              this.users = users;
    });
    githubUsers
              .searchUsers('scotch').subscribe(users => {
                console.log(users)
            });
  }

  goToDetails(login: string) {
    this.navCtrl.push(UserDetailsPage, {login});
  }

  search(searchEvent) {
    let term = searchEvent.target.value
    // 3 karakterden fazla ise arama yapılacak
    if (term.trim() === '' || term.trim().length < 3) {
      // cache kullanıcılarınıda alıyoruz
      this.users = this.originalUsers;
    } else {
      // Aranan kullanıcıları githubdan getir.
      this.githubUsers.searchUsers(term).subscribe(users => {
        this.users = users;
      });
    }
  }

}

Github kullanıcılarının orijinal sonuçlarını önbelleğe almak için bir originalUsers sınıfı özelliği ekledik.

Arama fonksiyonumuz, yalnızca arama parametresi 3'ten daha büyük karakter uzunluğuna sahip olduğunda çalışacak şekilde yapılandırılmıştır. Bu koşul sağlanmadığı zaman sonuçları sıfırladık (alphanumerik karakter dışındakiler çalışabilir biz sadece öğrenme amaçlı böyle yaptık).

http://localhost:8100 adresine gidip bir kullacı adı girin.

Sonuçlardan herhangi birine tıkladığınızda profiline gidecektir.

Uygulamayı Build/Run Etmek

ANDROID

Android sdk'yi kurmalısınız. Belirli platformunuz için kurulum talimatlarını burada bulabilirsiniz.

Uygulamanıza android platformu ekleyin

ionic platform add android

bu komut uygulamanızın klasöründeki platforms klasörüne android diye klasör ekler ve android uygulama geliştirmek için olan tüm dosyaları ekler.

Uygulamayı derleme

ionic build android

platforms/android/build/outputs yolunda apk dosyası görebilirsiniz bu dosyaı telefonunuza atarak uygulamanızı açabilirsiniz.

Kablo bağlıyken çalıştırma

ionic run android

Bunu çalıştırmadan önce telefonunuzu usb debugging modda bilgisayarınıza bağlamanız gerekiyor.

IOS

Ios için oluşturmak için, MacOs kullanıyor olmalısınız ve xCode kurmalısınız. Ayrıca tüm kullanıcılara kurulu şekilde (-g) olması gerekir. Bunkar sadece uygulama derleme ve dağıtıma  çıkarma konusunda yardımcı olurlar.

npm install -g ios-deploy

npm install -g ios-sim version

Projenize ios platform eklemelisiniz.

ionic platform add ios

bu komut uygulamanızın klasöründeki platforms klasörüne ios diye klasör ekler ve ios  uygulama geliştirmek için olan tüm dosyaları ekler.

Uygulamayı derleme

ionic build ios

Uygulamayı platforms/ios/build/emulator yoluna derler.

Sonra uygulamayı xCode ile birlikte gelen bir ios simülatöründe çalıştırın.

ionic run ios

Sonuç

Angular 2'nin nasıl işlediğine dair bir anlayışa sahip olduğunuzda, Ionic 2 Uygulamaları oluşturmak oldukça kolay, anlaşılır ve daha temiz. Ionic burada component (bileşenler) sağlar. Özellikle api'niz zaten bir yerde tanımlıysa, gerçekten hızlı bir şekilde bir uygulama oluşturabilirsiniz.

Bence, Ionic özellikle Aşamalı Web Uygulamaları'nın geliştirilmesinde önemli bir rol oynuyor. Eğer birisi onlara zaman ayırmak istiyorsa, Ionic’ e kesinlikle bir şans vermeliler. (Ganga Chris)

Evet arkadaşlar Ganga Chris ‘e teşekkür ediyorum. Gerçekten yararlı bir makale hazırlamış. Bende bunu elimden geldiğince türkçeleştirmeye çalıştım. Hatalarım veya yanlışlarım olabilir bu konuda yorum yaparak belirtebilirsiniz. Ben her zaman doğru olanın yanındayımdır. Okuduğunuzu için teşekkürler. İonic 2 ye geçiş hakkında tereddüt yaşayanlara bir ışık olduğunu düşünüyorum. Diğer paylaşımda görüşmek üzere :)

Yorumlar ({{totalCommentCount}})

  • mrx

    {{commentLike5Count}} beğenme 7 yıl önce

    Teşekkürler çeviri için bu konu hakkında devam makalelerini bekliyoruz :)
    Beğen Beğendin
  • HardCode

    {{commentLike8Count}} beğenme 7 yıl önce

    Üstad eline koluna sağlık. Çok güzel bir çeviri olmuş. Ne yazık ki Ionic 2 ile ilgili çok fazla Türkçe döküman yok. Eminim çok fazla boş zamanın yoktur ama daha fazla makale yazabilir / çevirebilirsen mükemmel olur tüm camia adına. Başarılar
    Beğen Beğendin
  • byCodersReplace

    {{commentLike15Count}} beğenme 6 yıl önce

    Kardeşim on numara iş çıkarttın HELAL olsun. Çalışmalarında başarıların daim olsun. ionic konusunda çalışmalarının devamını bekliyoruz. Mesela indoor map wi-fi yada ble ile alakalı bir konu çok yerinde olur şahsen. Şu ara bu konuyu araştırıyorum. Ama hangi platformda yazsam kararsız kalıyorum. Çok iyi bildiğimden değil hangi platformun geleceği daha iyi ve avantajlı olur düşüncesi var. Bu sebeple ionic e sıcak bakıyorum. Muhabbetle...
    Beğen Beğendin
  • Mert

    {{commentLike17Count}} beğenme 6 yıl önce

    Ellerinize, emeğinize sağlık. Gayet akıcı ve anlaşılır bir şekilde çeviri. Tebrikler.
    Beğen Beğendin
  • M.ali

    {{commentLike21Count}} beğenme 6 yıl önce

    Eline emeğine sağlık. Çok güzel bir anlatım olmuş
    Beğen Beğendin
  • Ahmet Muhammet Vural

    {{commentLike40Count}} beğenme 6 yıl önce

    Hocam ellerine saglik cok faydali oldu..
    Beğen Beğendin
  • Numan

    {{commentLike55Count}} beğenme 6 yıl önce

    Çok açıklayıcı ve güzel anlatımlı olmuş devamını Rest Api için bekliyorum
    Beğen Beğendin
  • Ahmet

    {{commentLike62Count}} beğenme 6 yıl önce

    merhabalar. size bir sorum olacak. uygulamayı android telefon üzerinde çalıştırmak istendiğinde. "The connection to the server was unsuccessful. (file://android_assest/www/index.html)" hatasını gidermenin yolu nasıl acaba?
    Beğen Beğendin
  • Abdurrahman Eker

    {{commentLike63Count}} beğenme 6 yıl önce

    Merhaba, Tam olarak sorunun kaynağını bilemiyorum. Eğer bu konuyu araştırıp sorunu çözemedi iseniz lütfen buraya: https://github.com/abdurrahmanekr/bana-istedigini-sor bir "issue" açın. Ben bir şeyler araştırdım, belki burada çözümü vardır: https://stackoverflow.com/questions/12319809/application-error-the-connection-to-the-server-was-unsuccessful-file-andr
    Beğen Beğendin
  • HardCode

    {{commentLike66Count}} beğenme 6 yıl önce

    @Ahmet; Aldığın hatanın genel olarak 3 sebebi var. 1-) Aynı ağda olmayabilirsiniz. Tekrar kontrol etmeni öneririm. 2-) Ağda port açılması gibi bir problem var veya fiewall engelliyor. 3-) ve en çok karşılaşılan; Timeout'a düşüyor. Bu durumda da config.xml dosyasındak <prefence etiketlerinin olduğu bölüme aşağıdaki kodu da ekle. <preference name="LoadUrlTimeoutValue" value="70000" /> Sorunun çözülmüş olmalı; kolay gelsin.
    Beğen Beğendin
  • süleyman

    {{commentLike168Count}} beğenme 3 yıl önce

    merhabalar öncelikle yazın çok başarılı yanlız benim şoyle bir sorum olacak. ben bır yerden hazır scrıpt aldım ve uygulama kodları yazılmı hazır dosyaları verdıler ıonıcte yazabılırsın dedıler. ama ıonıcten anlamıyorum yanı dosylarım hersey hazır sadece ıonıcte derleyıp pakete donusturecegım ama yapamadım hazır tema uzerınden nasıl yapılır anlatabılırmısın bır makale yazarak
    Beğen Beğendin
  • Düşündüklerin nedir ?

    Abdurrahman Eker

    (1010 Eylül 11111001100)

  • Full Stack Developer Turkey/Sivas
  • İnternette Avare Kodcu
  • coffee
  • github
  • instagram
  • linkedin
  • youtube
  • Yeni içeriklerden haberdar olmak ister misin ?