Android Retrofit Kullanımı ( Post İşlemi )

Merhaba arkadaşlar,
Mobilhanem.com sitemiz üzerinden anlattığımız/yayınladığımız Android  derslerimize Android Retrofit Kullanımı  ile devam ediyoruz. Retrofit nedir, nasıl kullanılır ve Retrofit de GET isteği nasıl yapılır gibi sorulara ayrıntılı olarak önceki dersimizde yer vermiştim. Şimdi ise Retrofit REST istemcisi ile POST isteğini sizlere anlatacağım.

Ayrıca diğer dersimizde Retrofit kütüphanesinin eski sürümünü kullandım bu dersimizde ise Retrofit 2.0 yapısı ile işlemleri gerçekleştireceğim.

Retrofit kütüphanesinin ayrıntılı olarak ne işe yaradığını bu dersimizi inceleyerek öğrenebilirsiniz. Direk kodlara geçelim ve gerekli işlemleri gerçekleştirelim. Uygulamamızda bir login sayfamız olacak kullanıcı adı ve şifre yazarak servise post yapacağız dönen cevaba göre de eğer kullanıcı adı ve şifremiz doğru ise kullanıcının bilgilerini ekranda göstereceğiz , eğer yanlış ise hata mesajını göstereceğiz.

Öncelikle projemize Retrofit kütüphanesini ve json parse işlemleri için kullanacağımız retrofinin gson kütüphanesini dahil ediyoruz.

build.gradle

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

Daha sonra uygulamamızın görsel kısmını hazırlayalım.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.mobilhanem.retrofitgetandpost.MainActivity">


    <TextView
        android:id="@+id/login_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:layout_marginTop="20dp"
        android:gravity="center_horizontal"
        android:text="Kullanıcı Girişi"
        android:textColor="#000"
        android:textSize="26sp" />

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/login_title"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:layout_marginTop="70dp"
        android:background="#fff"
        android:elevation="4dp"
        android:orientation="vertical"
        android:padding="20dp">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingTop="30dp">

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <EditText
                    android:id="@+id/userName"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:drawableLeft="@drawable/userprofile"
                    android:hint="Kullanıcı Adı" />
            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <EditText
                    android:id="@+id/userPassword"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="16dp"
                    android:drawableLeft="@drawable/userpassword"
                    android:hint="Şifre"
                    android:inputType="numberPassword" />
            </android.support.design.widget.TextInputLayout>

            <Button
                android:id="@+id/startBtn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:background="@color/colorPrimaryDark"
                android:text="Giriş Yap"
                android:textAllCaps="false"
                android:textColor="#fff"
                android:textSize="18sp" />
        </LinearLayout>
    </RelativeLayout>


</RelativeLayout>

Retrofit de ana kısmın url sini bütün API çağrıları için set edebilir , daha sonra interfaceleri Java’nın annotation larını kullanarak oluşturabiliriz.

Sunucudan istek yapabilmek için , interface methodunu çağırmak yeterlidir ve sonucunda bize dönüş objesi dönmektedir. Aşağıdaki yapıyı incelediğimiz zaman @Body kısmında servise UserInfo objesini gönderiyoruz. UserInfo objesinin içinde üç parametre bulunmaktadır. ( islem, kullaniciAdi ve sifre ) çünkü POST işlemini gerçekleştirirken servis yapısı bizde bu üç değişkeni beklemektedir.

Login olabilmemiz için : ( islem : musteriGiris , kullaniciAdi: musteri1 , sifre: 1234 )

RetrofitLoginService.java

package com.mobilhanem.retrofitgetandpost;

import com.mobilhanem.retrofitgetandpost.model.UserInfo;
import com.mobilhanem.retrofitgetandpost.model.UserResponse;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;

/**
 * Created by alper on 13/02/17.
 */

public interface RetrofitLoginService {

    @POST("api/index2.php")
    //@FormUrlEncoded
    Call<UserResponse> login(@Body UserInfo userInfo);

}

UserInfo sınıfımız aşağıdaki gibidir.

UserInfo.java

package com.mobilhanem.retrofitgetandpost.model;

/**
 * Created by alper on 16/02/17.
 */

public class UserInfo {

    public String islem;
    public String kullaniciAdi;
    public String sifre;

    public UserInfo(String islem,String kullaniciAdi,String sifre){

        this.islem = islem;
        this.kullaniciAdi = kullaniciAdi;
        this.sifre = sifre;

    }
}

MainActivity.java

MainActivity sınıfımızı incelersek; uygulama çalıştığında login sayfası karşımıza geliyor orada kullanıcı adı ve şifreyi yazıp Giriş Yap butonuna bastığımızda Retrofit isteği sunucuya gönderiyor yukarıda bahsettiğim gibi @Body annotation kullanarak body kısmında gerekli parametreleri gönderip girilen bilgiler eşleştiğinde kullanıcıyı login yaptırıyoruz. İstek yaparken Call methodunu kullanıyoruz ve gördüğünüz gibi UserResponse sınıfı ile çağrımızı gerçekleştiriyoruz dönen cevabı ise Callback yapısını kullanarak handle ediyoruz. onResponse methodunda dönen cevap doğru ise oluşan UserResponse objesini bir listeye atıp , Serializable yardımı ile diğer PersonProfileActivity e gönderiyoruz. Ayrıca bir json parse etme işlemine gerek kalmadan istediğimiz yapı oluşmuş oluyor. Retrofit 2 ile gelen özelliklerden Call ve Callback yapısı gerçekten işimizi çok kolaylaştırıyor. Uygulamanın kaynak kodunu indirip çalıştırmanız ve incelemeniz de faydalı olacaktır.

package com.mobilhanem.retrofitloginpost;

import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.mobilhanem.retrofitloginpost.model.UserInfo;
import com.mobilhanem.retrofitloginpost.model.UserResponse;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {

    private Button startBtn;
    private EditText userNameEdit, userPasswordEdit;
    private ProgressDialog progressDialog;
    public static final String BASE_URL = "http://vehbiakdogan.com/vakvak/servisci_panel/";
    private List<UserResponse> userResponseList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        startBtn = (Button)findViewById(R.id.startBtn);
        userNameEdit = (EditText)findViewById(R.id.userName);
        userPasswordEdit = (EditText)findViewById(R.id.userPassword);

        startBtn.setOnClickListener(clickListener);
    }
    private View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {


            if(!isEmpty(userNameEdit) && !isEmpty(userPasswordEdit)){

                postRequestMethod();

            }else if(isEmpty(userNameEdit)){
                userNameEdit.requestFocus();
                userNameEdit.setError("Lütfen kullanıcı adınızı giriniz!");
            }else {
                userPasswordEdit.requestFocus();
                userPasswordEdit.setError("Lütfen şifrenizi giriniz!");
            }
        }
    };

    private boolean isEmpty(EditText edittext) {
        if (edittext.getText().toString().trim().length() > 0)
            return false;

        return true;
    }

    private void postRequestMethod() {

        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setMessage("Lütfen Bekleyiniz");
        progressDialog.show();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RetrofitLoginService retrofitLoginService = retrofit.create(RetrofitLoginService.class);
        // userName : musteri1  password: 1234
        UserInfo userInfo = new UserInfo("musteriGiris",userNameEdit.getText().toString(),userPasswordEdit.getText().toString());
        Call<UserResponse> call = retrofitLoginService.login(userInfo);
        Log.w("request",call.request().toString());
        call.enqueue(new Callback<UserResponse>() {
            @Override
            public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
                progressDialog.dismiss();
                UserResponse userResponse = response.body();
                if(response.body()!=null && userResponse.isGiris()) {
                    userResponseList = new ArrayList<>();
                    userResponseList.add(userResponse);
                    Intent intent = new Intent(getApplicationContext(),PersonProfileActivity.class);
                    intent.putExtra("mylist", (Serializable) userResponseList);
                    startActivity(intent);
                }else{
                    Toast.makeText(getApplicationContext(),"Kullanıcı bilgileri hatalı veya bulunmamaktadır.",Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<UserResponse> call, Throwable t) {
                progressDialog.dismiss();

            }
        });
    }
}

UserResponse sınıfımızda aşağıdadır. Yukarıda bahsettiğim gibi sunucudan dönecek değerlerde neler olduğunu önce Postman de test edip baktıktan sonra bu yapıyı oluşturmamız çok daha kolay bir hale geldi.  İstek de bulunduğumuz url : http://vehbiakdogan.com/vakvak/servisci_panel/api/index2.php

UserResponse.java

package com.mobilhanem.retrofitloginpost.model;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

/**
 * Created by alper on 13/02/17.
 */

public class UserResponse implements Serializable {

    @SerializedName("islem")
    private String islem;
    @SerializedName("method")
    private String method;
    @SerializedName("hata")
    private String hata;
    @SerializedName("giris")
    private boolean giris;
    @SerializedName("bilgiler")
    private Bilgiler bilgiler;

    public String getIslem() {
        return islem;
    }

    public String getMethod() {
        return method;
    }

    public boolean isGiris() {
        return giris;
    }

    public String getHata() {
        return hata;
    }

    public Bilgiler getBilgiler() {
        return bilgiler;
    }
}

UserResponse sınıfımızın içinde yer alan ve sunucudan çektiğimiz uygulama içinde de kullanacağımız kullanıcı bilgilerini içinde barındıran Bilgiler sınıfımızda aşağıdadır.

Bilgiler.java

package com.mobilhanem.retrofitloginpost.model;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

/**
 * Created by alper on 13/02/17.
 */

public class Bilgiler implements Serializable {
    @SerializedName("soforID")
    private String soforID;
    @SerializedName("firmaID")
    private String firmaID;
    @SerializedName("adSoyad")
    private String adSoyad;
    @SerializedName("tc")
    private String tc;
    @SerializedName("telefon")
    private String telefon;
    @SerializedName("tecrubeYil")
    private String tecrubeYil;
    @SerializedName("ehliyetSinifi")
    private String ehliyetSinifi;
    @SerializedName("kullaniciAdi")
    private String kullaniciAdi;
    @SerializedName("firmaUnvan")
    private String firmaUnvan;
    @SerializedName("isfirmaTelefonlem")
    private String firmaTelefon;
    @SerializedName("firmaFax")
    private String firmaFax;
    @SerializedName("islefirmaEpostam")
    private String firmaEposta;
    @SerializedName("firmaKullaniciAdi")
    private String firmaKullaniciAdi;
    @SerializedName("firmaYetkili")
    private String firmaYetkili;
    @SerializedName("hatID")
    private String hatID;
    @SerializedName("hatNo")
    private String hatNo;
    @SerializedName("hatAciklama")
    private String hatAciklama;
    @SerializedName("musteriEposta")
    private String musteriEposta;
    @SerializedName("musteriKullaniciAdi")
    private String musteriKullaniciAdi;

    public String getTecrubeYil() {
        return tecrubeYil;
    }

    public void setTecrubeYil(String tecrubeYil) {
        this.tecrubeYil = tecrubeYil;
    }

    public String getSoforID() {
        return soforID;
    }

    public void setSoforID(String soforID) {
        this.soforID = soforID;
    }

    public String getFirmaID() {
        return firmaID;
    }

    public void setFirmaID(String firmaID) {
        this.firmaID = firmaID;
    }

    public String getAdSoyad() {
        return adSoyad;
    }

    public void setAdSoyad(String adSoyad) {
        this.adSoyad = adSoyad;
    }

    public String getTc() {
        return tc;
    }

    public void setTc(String tc) {
        this.tc = tc;
    }

    public String getTelefon() {
        return telefon;
    }

    public void setTelefon(String telefon) {
        this.telefon = telefon;
    }

    public String getEhliyetSinifi() {
        return ehliyetSinifi;
    }

    public void setEhliyetSinifi(String ehliyetSinifi) {
        this.ehliyetSinifi = ehliyetSinifi;
    }

    public String getKullaniciAdi() {
        return kullaniciAdi;
    }

    public void setKullaniciAdi(String kullaniciAdi) {
        this.kullaniciAdi = kullaniciAdi;
    }

    public String getFirmaUnvan() {
        return firmaUnvan;
    }

    public void setFirmaUnvan(String firmaUnvan) {
        this.firmaUnvan = firmaUnvan;
    }

    public String getFirmaTelefon() {
        return firmaTelefon;
    }

    public void setFirmaTelefon(String firmaTelefon) {
        this.firmaTelefon = firmaTelefon;
    }

    public String getFirmaFax() {
        return firmaFax;
    }

    public void setFirmaFax(String firmaFax) {
        this.firmaFax = firmaFax;
    }

    public String getFirmaEposta() {
        return firmaEposta;
    }

    public void setFirmaEposta(String firmaEposta) {
        this.firmaEposta = firmaEposta;
    }

    public String getFirmaKullaniciAdi() {
        return firmaKullaniciAdi;
    }

    public void setFirmaKullaniciAdi(String firmaKullaniciAdi) {
        this.firmaKullaniciAdi = firmaKullaniciAdi;
    }

    public String getFirmaYetkili() {
        return firmaYetkili;
    }

    public void setFirmaYetkili(String firmaYetkili) {
        this.firmaYetkili = firmaYetkili;
    }

    public String getHatID() {
        return hatID;
    }

    public void setHatID(String hatID) {
        this.hatID = hatID;
    }

    public String getHatNo() {
        return hatNo;
    }

    public void setHatNo(String hatNo) {
        this.hatNo = hatNo;
    }

    public String getHatAciklama() {
        return hatAciklama;
    }

    public void setHatAciklama(String hatAciklama) {
        this.hatAciklama = hatAciklama;
    }

    public void setMusteriEpostausteriEposta(String musteriEposta) {
        this.musteriEposta = musteriEposta;
    }
    public String getMusteriEposta() {
        return musteriEposta;
    }
    public String getMusteriKullaniciAdi() {
        return musteriKullaniciAdi;
    }

}

Login başarılı olduktan sonra dönen cevaptaki bazı bilgileri RecyclerView kullanarak CardView içinde gösteriyoruz.

PersonProfileActivity.java

package com.mobilhanem.retrofitloginpost;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.mobilhanem.retrofitloginpost.adapter.CustomAdapter;
import com.mobilhanem.retrofitloginpost.model.UserResponse;

import java.util.List;

public class PersonProfileActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private RecyclerView.LayoutManager mLayoutManager;
    private RecyclerView.Adapter mAdapter;
    private List<UserResponse> userResponses;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_person_profile);

        Intent i = getIntent();
        userResponses = (List<UserResponse>) i.getSerializableExtra("mylist");

        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mAdapter = new CustomAdapter(userResponses);
        mRecyclerView.setAdapter(mAdapter);


    }
}

RecyclerView için oluşturduğumuz Adapter sınıfımızdaki kodlarda aşağıdadır.

CustomAdapter.java

package com.mobilhanem.retrofitgetandpost.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.mobilhanem.retrofitgetandpost.R;
import com.mobilhanem.retrofitgetandpost.model.UserResponse;

import java.util.List;

/**
 * Created by alper on 19/02/17.
 */

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.PersonViewHolder> {

    private List<UserResponse> userResponses;
    public static class PersonViewHolder extends RecyclerView.ViewHolder {
        TextView personName;
        TextView personEmail;
        TextView personPhone;
        TextView companyName;
        TextView ehliyetSinifi;
        TextView experienceYear;

        PersonViewHolder(View itemView) {
            super(itemView);
            personName = (TextView)itemView.findViewById(R.id.customer_name);
            personEmail = (TextView)itemView.findViewById(R.id.customer_email);
            personPhone = (TextView)itemView.findViewById(R.id.customer_phone);
            companyName = (TextView)itemView.findViewById(R.id.company_name);
            ehliyetSinifi = (TextView)itemView.findViewById(R.id.ehliyetSinifi);
            experienceYear = (TextView)itemView.findViewById(R.id.experince_year);
        }
    }

    public CustomAdapter(List<UserResponse> userResponses){
        this.userResponses = userResponses;
    }

    @Override
    public PersonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_item, parent, false);
        PersonViewHolder pvh = new PersonViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(PersonViewHolder holder, int position) {
        holder.personName.setText("Kullanıcı Adı:"+"  "+userResponses.get(position).getBilgiler().getMusteriKullaniciAdi());
        holder.personPhone.setText("Telefon Numarası:"+"  "+userResponses.get(position).getBilgiler().getTelefon());
        holder.personEmail.setText("E-posta:"+"  "+userResponses.get(position).getBilgiler().getMusteriEposta());
        holder.companyName.setText("Firma Ünvan:"+"  "+userResponses.get(position).getBilgiler().getFirmaUnvan());
        holder.ehliyetSinifi.setText("Ehliyet Sınıfı:"+"  "+userResponses.get(position).getBilgiler().getEhliyetSinifi());
        holder.experienceYear.setText("Tecrübe Yılı:"+"  "+userResponses.get(position).getBilgiler().getTecrubeYil());
    }

    @Override
    public int getItemCount() {
        return userResponses.size();
    }
}

Login olmadan önce ekran görüntüsü:

Login olduktan sonra ekran görüntüsü:

İşte arkadaşlar Retrofit ile POST işleminin nasıl olduğunu sizlere anlatmaya çalıştım. Ayrıca GET, PUT, DELETE gibi metodlar da var, bunların kullanımı da öğrenmek şart.

Mobilhanem.com üzerinden anlattığımız mobil uygulama geliştirme derslerine devam edeceğiz. Konu hakkında sorunuzu yorum alanından sorabilirsiniz. Konu dışı sorularınızı ve tüm yazılımsal sorularınızı sorucevap.mobilhanem.com sitemizden de sorabilirsiniz.

Bir dahaki dersimizde görüşmek dileğiyle..

Tüm Android Ders, Proje ve Kaynak Kodlar için tıklayınız.

3

Alper Beyler

Yüksek Lisans: Çankaya Üniversitesi / Bilgisayar Mühendisliği
Lisans: Çankaya Üniversitesi / Bilgisayar Mühendisliği (4/3.30) (2010-2014)
Lisans : Viyana Teknik Üniversitesi / Bilgisayar Bilimleri (2013)

11 Yorum

  • call.enqueue methodunu bir helper classı icinde yazdigmizi dusunursek response sonucunda donen listeyi activtye nasil return edebiliriz. yaptigim calismalarda once null listeyi donduruyor. listeyi doldurduktan sonra tekrar activitye gitmiyor.

    • Merhaba buradaki dersin kaynak kodunu indirip çalıştırdınız mı ? onResponse methodunda UserResponse objesi dönüyor gördüğünüz gibi dönen cevabı Listeye atıp diğer Activity e gönderiyoruz. sizin sorunuz için eğer servisinizden dönen bir obje değilde bir liste ise aynı şekilde ilgili Activitye gönderebilirsiniz. ( Intent ile yada EventBus kullanarak )

      • Senaryoyu şu şekilde anlatayım. ContentListActivity adında bir activity im var. Bu sayfada bir takım veriler göstereceğim. Veri çekme işlemini ContentHelper adında bir classta GetContentList methodunda yapıyorum. Farklı activitylerde kullanmak için bu methodu ayrı classta yazdım. Activity den ContentHelper.GetContentList(); şeklinde gönderdiğimde ben bu listeyi nasıl alacağım. Farklı bir activity intent olarak gönderebiliyoruz listeyi sizin yaptığınız şekilde. Aynı activity e nasıl geri dönecek bu liste intent le oluyormu bilmiyorum. Yardımınızı bekliyorum.

        • bu dersteki gibi interface methodu oluşturup kullanırsın istediğin activity de ayrı bir interface tanımlayarak da methodunu oluşturup listeyi set ve get leri tanımlarsın bu şekilde get ile ilgili listeyi çekebilirsin umarım anlamışımdır sorunuzu 🙂 ayrıca activity lerin haberdar olmasını istiyorsan intent ile veri göndermekle uğraşma EventBus dersimiz var onu bir incelemen faydalı olacaktır.
          https://www.mobilhanem.com/android-eventbus-kutuphanesi-kullanimi/

    • güzel olurdu tabiki 🙂 planlarımız arasında var fakat henüz gerçekleştiremedik.

  • hocam bende benzer bir uygulama yaptım farklı bir link kullanarak ancak login butonuna tıkladığımda progress çalışıyor ve kısa bir süre sonra hata veriyor uygulama
    hata şu şekilde
    “java.lang.RuntimeException: Parcel: unable to marshal value com.mrt.bk.UserResponse@55d808d”

    Çözümü hakkında bir fikriniz var mı şimdiden teşekkürler

    • Merhaba, farklı bir link kullanıyorsanız sizin web servis bağlantınızda farklı olacaktır servisten dönen cevaplarda neler var ona bakmalısınız.. UserResponse objesinin içinde yer alan değerler servisteki değerlerle birebir eşleşmesi gerekiyor fakat sizin servisten dönen cevapta parse edemiyor anladığım kadarıyla.

  • Merhaba,

    Türkçe kararter verileri çekmekde sorun yaşıyorum. Nasıl bir çözüm önerirsiniz?
    Lütfen çok acil cevaplarınızı rica ediyorum.

  • Gerçekten güzel bir örnek emeğinize sağlık. Uygulamayı indirdim paketler ve diğer kısımlarda herhangi bir sorun yok. Sanırın json url güncellenmiş sanırım sizin gördüğünüz sonucu göremedim. Yardımcı olurmusunuz

Haftalık Bülten

Mobilhanem'de yayınlanan dersleri haftalık mail almak ister misiniz?