نحوهی تعامل با سرویس پایگاه داده بکتوری قبل از انتشار SDK اندروید آن
سرویس پایگاه داده (Database) بکتوری به توسعهدهنده کارخواه (client) این امکان را میدهد که objectهای کدش را در سرور ذخیره کند. متاسفانه در حال حاضر SDK اندروید این سرویس هنوز آماده نشده است اما در این پست نحوهی تعامل با سرویس پایگاه داده را با استفاده از SDK رایانش (Cloud-code) و یا تعامل با Endpointهای REST این سرویس در اندروید نشان میدهیم.
مقدمات
فرض میکنیم که در برنامهمان کلاسی به نام User داریم که شامل نام، نام خانوادگی، پست الکترونیکی و تلفن یک کاربر است و میخواهیم یک نمونه آن را در پایگاه داده ذخیره کنیم.
1- یک پروژه جدید در اندروید استودیو بسازید. (در قسمت اضافه کردن Activity جدید، Activity خالی را انتخاب کنید.) (لینک تکمیلی)
2- در فایل AndroidManifest.xml باید اجازهی دسترسی به Internet را به برنامه بدهید. برای این کار خط زیر را به این فایل اضافه کنید.
<uses-permission android:name="android.permission.INTERNET"/>
اکنون فایل Manifest شما باید چیزی شبیه این باشد:
3- به پنل پایگاه داده برنامهتان بروید، یک جدول جدید بسازید (در این مطلب نام جدول را userTable فرض کردهایم). ستونهایی برای نام، نام خانوادگی، پست الکترونیکی و تلفن –همگی از جنس string– به این جدول اضافه کنید. (آشنایی بیشتر با نحوه کار با پنل پایگاه داده)
4- یک کلاس به نام User در پروژه اندروید اضافه کنید. نام اعضای این کلاس را مطابق با ستونهای جدولی که در پنل تعریف کردید (userTable) بگذارید.
public class User {
public String name, lastName, email, phone;
public User(String name, String lastName, String email, String phone) {
this.name = name;
this.lastName = lastName;
this.email = email;
this.phone = phone;
}
}
ذخیره سازی با استفاده از Endpointهای REST
مستندات تعامل با Endpointهای REST پایگاه داده در این لینک قابل مشاهده است. اکنون در اندروید با استفاده از OkHttp که یک کتابخانه معتبر برای ارسال درخواستهای Http است یک درخواست (request) Http میسازیم که یک کاربرمان را ذخیره کند.[1]
1- OkHttp را به پروژه خود اضافه کنید. برای این کار خط زیر را به فایل build.gradle ماژول برنامهتان (معمول به نام app) اضافه کنید و gradle را sync کنید. (Ctrl+Shit+G)
compile 'com.squareup.okhttp3:okhttp:3.4.1'
:اکنون فایل build.gradle شما باید چیزی شبیه به این باشد
apply plugin: 'com.android.application'android {compileSdkVersion 24defaultConfig {buildToolsVersion "24.0.2"minSdkVersion 15applicationId "com.backtory.blog.objectstorage"targetSdkVersion 24testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"versionCode 1 versionName "1.0" } buildTypes { release {proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'minifyEnabled false } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar'])exclude group: 'com.android.support', module: 'support-annotations'androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' compile 'com.squareup.okhttp3:okhttp:3.4.1'}
2- اکنون به قسمت فرستادن درخواست رسیدهایم. این درخواست را میتوانید مثلا در پاسخ به کلیک شدن یک دکمه بفرستید.
همچنین دقت کنید که برای اینکه کاربر برنامه شما بتواند در پایگاه داده اطلاعات ذخیره کند باید ورود (login) کرده باشد. شما باید همراه با درخواست ذخیرهسازیتان access_token کاربر وارد شده را بفرستید.
کد activity شما در پایان این گام میتواند شبیه به این کد باشد:
public class MainActivity extends AppCompatActivity {
private Button saveUserButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
saveUserButton = (Button) findViewById(R.id.button);
saveUserButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Get this value from user, for example by defining EditTexts in the layout file.
User user = new User("<user name>", "<user lastname>", "<user email>", "<user phone number>");
new SaveUserAsyncTask().execute(user);
}
});
}
private class SaveUserAsyncTask extends AsyncTask<User, Void, Response>{
@Override
protected Response doInBackground(User... users) {
User user = users[0];
JSONObject userJsonObject = new JSONObject();
try {
userJsonObject.put("name", user.name);
userJsonObject.put("lastName", user.lastName);
userJsonObject.put("email", user.email);
userJsonObject.put("phone", user.phone);
OkHttpClient client = new OkHttpClient();
String accessToken = login(client);
Request storageRequest = new Request.Builder()
.url("https://api.backtory.com/object-storage/classes/userTable/")
.post(RequestBody.create(MediaType.parse("application/json"), userJsonObject.toString()))
.addHeader("Authorization", "Bearer " + accessToken)
.addHeader("X-Backtory-Object-Storage-Id", "575d1432e4b099f61fd535cf")
.build();
return client.newCall(storageRequest).execute();
} catch (JSONException | IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Response response) {
// do UI work here
}
private String login(OkHttpClient client) throws IOException, JSONException{
// in order to use backtory database service, we need a access-token
// here we login as guest before sending database request.
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("username", "objectstorage")
.addFormDataPart("password", "1")
.build();
Request loginRequest = new Request.Builder()
.url("https://api.backtory.com/auth/login/")
.post(requestBody)
.header("X-Backtory-Authentication-Id", "575d1432e4b099f61fd535cd")
.header("X-Backtory-Authentication-Key", "575d1432e4b006215e29ad9a")
.build();
Response loginResponse = client.newCall(loginRequest).execute();
return new JSONObject(loginResponse.body().string()).getString("access_token");
}
}
}
}
تمام شد! با کلیک شدن کلید، AsyncTask شروع به کار کرده و تابع doInBackground آن اطلاعات کاربر را ذخیره میکند. چنانچه دوست دارید در جواب این درخواست کاری مرتبط با UI برنامه انجام دهید (مثلا نتیجه عملیات را به کاربر نشان دهید) تابع onPostExecute کلاس AsyncTask مکان مناسبی برای آن کار است.
ذخیره سازی با استفاده از سرویس رایانش
علاوه بر روش قبلی، میتوان جهت ذخیره یک object، یک تابع cloud-code تعریف کرد و در سمت اندروید با استفاده از SDK اندروید بکتوری آن تابع را فراخوانی کرد.
1- SDK بکتوری را در فایل build.gradle ماژول برنامهتان (معمولا به نام app) به پروژه اضافه کنید. فایل build.gradle شما باید چیزی شبیه به این باشد:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "com.backtory.blog.objectstorage"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories {
maven {
url 'https://dl.bintray.com/pegah-backtory/maven/'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
compile 'com.backtory.android:backtorysdk:0.2.2'
}
2- به پنل برنامهتان بروید و در بخش رایانش یک تابع جدید بسازید. در این متن نام تابع را insertData گرفتهایم. (اطلاعات بیشتر در مورد پنل رایانش و تعریف تابع)
var Backtory = require('backtory-sdk');
var userTable = Backtory.Object.extend("userTable");
exports.handler = function(requestBody, context) {
var user = new userTable();
user.set("name", requestBody.name);
user.set("lastName", requestBody.lastName);
user.set("email", requestBody.email);
user.set("phone", requestBody.phone);
user.save({
success: function(result) {
context.succeed(result);
},
error: function(error) {
context.fail(error);
}
});
};
دقت کنید که در خطوط user.set… نام کلیدها با نام ستونهای جدول userTable که در پنل تعریف کردیم باید یکی باشد.
3- اکنون در کد اندروید ابتدا باید SDK بکتوری را راهاندازی (setup) کنید. بدین منظور باید تابع Backtory.init با کلیدهای برنامه شما که از پنل قابل دسترسی است در تابع onCreate از Activity شما فراخوانی شود. (اطلاعات بیشتر و نحوهی مناسبتر راه اندازی SDK)
4- برای سادگی مثال ما در گام ساختن یک نمونه از User، مقادیر اعضا را در کد وارد کردهایم، شما میتوانید با تعریف کردن EditText در layout خود مقادیر را از کاربر برنامهتان بگیرید.
5- سرویس رایانش اجازهی فراخوانی توابع را بدون نیاز به login بودن کاربران میدهد. در مورد مثال ما، دیگر لازم نیست کاربران برنامهتان حتما به اکانت بکتوری شان ورود کنند، هرچند login کردن کاربران با SDK بکتوری بسیار ساده است و پس از یکبار وارد شدن، SDK کاربر را در وضعیت وارد شده نگه میدارد. (اطلاعات بیشتر). اکنون کافی است تابعی که در پنل تعریف کردیم را با کمک تابع BacktoryCloudCode.runInBackground فراخوانی کنیم. Activity شما در پایان این گام باید حدودا مشابه این تصویر باشد:
public class MainActivity extends AppCompatActivity { private TextView textView; private Button saveUserButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); saveUserButton = (Button) findViewById(R.id.button); textView = ((TextView) findViewById(R.id.textView)); Backtory.init(this, Config.newBuilder() .storage(new Storage.SharedPreferencesStorage(this)) .initAuth("575d1432e4b099f61fd535cd", "575d1432e4b006215e29ad9a") .initCloudCode("575d1433e4b099f61fd535d1") .build()); saveUserButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Get this value from user, for example by defining EditTexts in the layout file. User user = new User("<user name>", "<user lastname>", "<user email>", "<user phone number>"); BacktoryCloudCode.runInBackground("insertData", user, Void.class, new BacktoryCallBack<Void>() { @Override public void onResponse(BacktoryResponse<Void> backtoryResponse) { textView.setText(backtoryResponse.isSuccessful() ? "ذخیره شد!" : backtoryResponse.message()); } }); } }); } }
حرف آخر
همانطور که دیدیم با SDK بکتوری کد سادهتر و تمیزتر شد. همچنین امکانات دیگر SDK مانند مدیریت login کاربران این امکان را به شما میدهد که زمان کمتری در توسعه برنامه مصرف کنید.