روزنوشت

می نویسم؛ تا به یاد آورم روزی، بودم

روزنوشت

می نویسم؛ تا به یاد آورم روزی، بودم

روزنوشت

من آرزویی ندارم، من از چیزی نمی‌ترسم، من آزادم...

«کازانتزاکیس»

دنبال کنندگان ۳ نفر
این وبلاگ را دنبال کنید
آخرین نظرات

پنل مدیریت وان سیگنال از مدتها پیش تنها با فیلتر شکن باز می‌شد اما کاربرهایی که IP ایران رو داشتند بدون مشکل در OneSignal رجیستر می‌شدن و در نتیجه مشکلی برای ارسال Push Notification وجود نداشت.

چندماه پیش بود که خبر اومد که APIهای وان سیگنال به روی کاربران ایرانی بسته شده و در نتیجه کاربرهامون دیگه تو سرویس وان سیگنال رجیستر نمیشن و عملاً این سرویس برای توسعه‌دهنده‌گان ایرانی که هدفشون بازار ایران هست کاربردی نداره.

 

همون زمان‌ها خاطرم هست که مطلبی رو خوندم که اشاره شده بود چون مشکل فقط در مرحله‌ی اول و دریافت Player ID هست، اگر این API رو از طریق سرور خودمون ارسال کنیم مشکل حل میشه.

 

چند هفته پیش لازم شد تا در پروژه‌ی جدید از سرویس Push Notification استفاده کنم. تو این پروژه اپ Android و iOS داریم و خب باید از سرویسی استفاده کنیم که هردو رو ساپورت کنه.

 

با توجه به ماجرای OneSignal اول از همه رفتم سمت سرویس‌های ایرانی و البته سرویس FCM خود گوگل. در تست من، مشکلی در سرویس FCM وجود نداشت و Device token به درستی دریافت می‌شد، البته وقتی تلاش کردم به همه‌ی کاربران از طریق پنل FCM پوش ارسال کنم، ناموفق بود اما اگر تنها یک Device رو هدف قرار می‌دادم، پوش به درستی دریافت می‌شد. برای من محرز شد که FCM مشکلی در رجیستر کردن کاربران (حداقل در اندروید) نداره و نهایتاً باید پنلی براش بنویسم یا اینکه از گزینه‌های اوپن سورس موجود (پنل هایی که برای ارسال پوش از FCM استفاده می‌کنن) که تعدادشون کم هم نبود استفاده کنم. تنها مشکل این بود که دولوپر iOS نتیجه‌ی دیگری گرفته بود که در iOS بدون فیلتر شکن کاربران در سرویس FCM رجیستر نمیشن. که البته برای من عجیب بود این اختلاف در دو پلتفرم (که البته راهی برای رد یا تاییدش درحال حاضر ندارم)

 

پس از اون سرویس‌های ایرانی رو بررسی کردیم، پوشه اولین گزینه بود اما ظاهراً SDK مختص iOS نداره هنوز و به همین دلیل حذف شد. سایر سرویس ها هم یا قیمت بالایی داشتن و یا پیچیدگی زیادی در پیاده سازی داشتن (که خب باعث شد اطمینان کمتری به کیفیت سرویس در من ایجاد بشه).

 

نهایتن تصمیم گرفتم مشکل OneSignal رو حل کنم. چون قبلن هم در چندین پروژه ازش استفاده کرده بودم و کلی متد کمکی برای شرایط متفاوت براش نوشته بودم که اینجا هم با دردسری کمتری می‌تونستم ازشون بهره ببرم، اما چون مطلبی که چندماه پیش خونده بودم رو پیدا نکردم، خودم شروع به پیاده‌سازیش کردم و دلیل اصلی نوشتن این پست هم همین هست، شاید در شرایطی به کمک دیگری بیاد.

 

با بررسی SDK وان سیگنال برای اندروید و iOS متوجه شدم که رفع مشکل خیلی ساده هست و و کافیه چیزی شبیه پروکسی سمت سرور ایجاد بشه تا درخواست ها از اون طریق ارسال بشه و در SDK هم تغییرات اندکی ایجاد بشه.

 

Android:

 

iOS:

 

اگه لینک‌های بالا رو بررسی کنید می‌بینید که خیلی راحت میشه درخواست ها رو به Url دیگری ارسال کرد. کافیه که سروری در خارج کشور داشته باشیم و یک API ساده که همه‌ی درخواست ها رو دریافت کنه، به سمت سرور OneSignal ارسال کنه و پاسخ رو برگردونه.

 

کد زیر به زیان PHP و فریم‌وورک Slim هست. البته مشخصه که مفهوم کلی بسیار ساده هست و با هر زبان دیگه و یا هر فریم‌وورکی قابل پیاده سازی هست:

 

<?php
require_once __DIR__ . '/vendor/autoload.php';

use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

$app = new Slim\App();

//region Helper Functions
function startsWith($haystack, $needle) {
    // search backwards starting from haystack length characters from the end
    if (is_array($needle)) {
        foreach ($needle as $str) {
            if (strrpos($haystack, $str, -strlen($haystack)) !== FALSE) {

                return TRUE;
            }
        }

        return FALSE;

    }

    return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== FALSE;
}

/**
 * @param Response $response
 * @param string|array $body
 * @param int $status
 *
 * @return \Psr\Http\Message\ResponseInterface
 */
function postResponse(Response $response, $body, $status = 200) {
    $response->getBody()->write(is_array($body) ? json_encode($body, JSON_UNESCAPED_UNICODE) : $body);

    return $response->withStatus($status > 0 ? $status : 200);
}

/**
 * @param Request $request
 *
 * @return array
 */
function getInputData(Request $request) {
    $data = $request->getParsedBody();
    if (empty($data)) {
        $data = $request->getQueryParams();
        if (empty($data)) {
            $data = $_REQUEST;
        }
    }

    if (startsWith($data, "{") || startsWith($data, "[")) {
        return json_decode($data, TRUE);
    }
    parse_str($data, $array);

    return $array;

}
//endregion

$app->any('/one_signal[/{params:.*}]', function (Request $request, Response $response, $args) {
    $method      = $request->getMethod();
    $sentHeaders = $request->getHeaders();
    $uri         = $args['params'];
    $body        = getInputData($request);
    $headers     = [];
    foreach ($sentHeaders as $header => $value) {
        $normalizedHeader = str_replace('HTTP_', '', $header);
        if (startsWith($normalizedHeader, 'HOST')) {
            continue;
        }
        $headers[$normalizedHeader] = $value[0];
    }
    foreach ($body as $key => $value) {
        $correctType = $value;
        if (in_array($key, ['device_type', 'timezone', 'session_count', 'created_at', 'playtime', 'badge_count',
                            'last_active', 'notification_types', 'test_type', 'net_type', 'game_version'])) {
            $correctType = (int)$value;
        } else {
            if (in_array($key, ['lat', 'long'])) {
                $correctType = (double)$value;
            } else {
                if ($key == 'rooted') {
                    $correctType = filter_var($value, FILTER_VALIDATE_BOOLEAN);
                }
            }
        }


        $body[$key] = $correctType;
    }
    
    $client  = new Client();
    $options = [
        'headers' => $headers
    ];
    if (strtolower($method) != 'get') {
        $options['json'] = $body;
    }
    $result = $client->request($method, "https://onesignal.com/api/v1/{$uri}", $options);
    
    $responseHeaders = $result->getHeaders();
    foreach ($responseHeaders as $header => $value) {
        $response->withAddedHeader($header, is_array($value) ? $value[0] : $value);
    }
    return postResponse($response, (string)$result->getBody());
});

$app->run();

 

اینجا از پکیج Slim Framework برای ساخت API استفاده شده که با Composer به پروژه اضافه‌ش کنید:

composer require slim/slim "^3.0"

 

برای ارسال درخواست‌های HTTP هم از کتابخانه‌ی Guzzle استفاده شده:

composer require guzzlehttp/guzzle:~6.0

 

البته باید توجه داشته باشید که در این کدها، هیچ عامل محدود‌کننده گزاشته نشده، یعنی اگه فرد دیگری به این API درخواست رو ارسال کنه می‌تونه تو اپ خودش ازش استفاده کنه، که خب می‌تونه سربار زیادی برای سرورتون ایجاد کنه. منطقی هست که مقدار app_id در دیتای ورودی رو چک کنید و اگر متفاوت از app_id مختص خودتون بود، پیغام خطا بدید و درخواست رو رد کنید.

if ($body['app_id'] != "YOUR_APP_ID") {
    return postResponse($response, ['error_code' => -100, 'error_message' => 'Request rejected'], 400);
}

حالا کافیه که SDK رو به پروژه‌ی اندروید یا iOS اضافه کنید، و مقادیری که در ابتدای پست بهش اشاره شد رو به آدرس سرور خودتون تغییر بدید.

مثلاً به جای https://onesignal.com/api/v1/ از آدرس https://your-domain.com/one_signal/ استفاده کنید

 

برای اندروید سورس SDK رو دانلود کنید و بعنوان ماژول به پروژه اضافه کنید و اون خط رو تغییر بدید. برای iOS هم به همین شکل.

 

البته ناگفته نماند که در انتهای تحقیقات برای یافتن جایگزین OneSignal به سایت https://yeksignal.com رسیدم، اما چون راه‌حل ساده‌تر از چیزی بود که فکر می‌کردم و سرور خارج از ایران هم داشتم نیازی به استفاده از این سرویس ندیدم. اگر سرور خارج از ایران ندارید و مجبورید سرور جداگانه تهیه کنید، شاید برای شما گزینه‌ی معقولی باشه.

 

 

  • Nevercom

روزهای تلخ اکلیپس و ADT Bundle رو همه به خاطر داریم...

نوشتن و اضافه کردن کتابخانه ها دردسر خودش رو داشت، Cleanهای مداوم رو همه به یاد داریم.

Emulator از اون زمان تا حالا خیلی بهتر شده و واقعن سریعتر شده

 

Android Studio یک IDE خیلی خوب هست و کیفیت کار رو برای برنامه نویس های اندروید بالاتر برده، Gradle هم یک Build System منعطف و قوی هست که امکانات جدیدی رو در اختیارمون گذاشته که خیلی به سریعتر شدن پروسه ی برنامه نویسی یا انتشار برنامه ها کمک می کنه.

 

با همه ی اینها نمیتونیم انکار کنیم که فرآیند Build اپ ها در دوران اکلیپس و ANT خیلی سریعتر بود. پیچیدگی های خود Gradle به یک طرف، استفاده از اینترنت و تحریم بودن ایران هم از طرف دیگه باعث شده پروسه ی Build خیلی کند بشه.

 

در این بین راه حل هایی وجود داره که میتونه به تسریع پروسه ی Build کمک کنه.

 

Gradle Offline Mode

درواقع Gradle برای انجام کارش نیاز به اینترنت داره، تا چک کنه که همه ی بسته هایی که برنامه نیاز داره رو اگر وجود نداشت دانلود کنه، یا بسته به پلاگین هایی که نصب کردیم (مثل fabric.io) اطلاعاتی رو ارسال کنه. اما چون وضعیت اینترنت ما تعریفی نیست، سایت bintray.com که مخازن jCenter اونجا هاست میشن ایران رو تحریم کرده، و اینکه همیشه نیاز نیست Gradle بروز بودن بسته ها رو چک کنه، تغییر Gradle به حالت Offline میتونه پروسه ی Build رو کمی سرعت ببخشه.

 

من تنها زمانی که میخوام کتابخانه ی جدیدی به پروژه اضاف کنم یا Build نهایی برای Release بگیرم، Gradle رو از حالت Offline بر میدارم.

 

 

تنظیمات gradle.properties

علاوه بر این می تونید خود Gradle رو به شکلی کانفیگ کنید که نتیجه ی اون افزایش سرعت Build باشه

 

 

همونطور که می بینید تو هر پروژه ی اندروید، اندروید استودیو دو فایل gradle.propertes رو بهتون نشون میده

  • Project Properties: تنظیماتی که مختص همون پروژه هستن و فقط روی اون پروژه اعمال میشن (این فایل توی هر پروژه وجود داره)
  • Global Properties: تنظیمات عمومی Gradle که روی همه ی پروژه ها تاثیر میزاره، این فایل تو پروژه ای که ایجاد می کنید وجود نداره و وقتی روش دابل کلیک کنید، فایلی رو خارج از محیط پروژه باز می کنه. این فایل در مسیر زیر وجود داره
    • لینوکس:
~/.gradle/gradle.properties
  • ویندوز
%userprofile%/.gradle/gradle.properties

 

اگه این فایل (Global Properties) تو این مسیر وجود نداشت (و مثل تصویر بالا تو اندروید استودیو نمایش داده نشد) ، باید ایجادش کنید.

 

 

نمونه تنظیماتی که من استفاده می کنم:

 

org.gradle.daemon=true
org.gradle.jvmargs=-Xmx2048M
org.gradle.configureondemand=true
org.gradle.parallel=true

 

  • org.gradle.daemon=true: این خط به Gradle دستور میده که در حالت daemon اجرا بشه (daemon رو شاید معادل service در ویندوز بشه درنظر گرفت). اینکار باعث میشه که یه پروسه ی مجزا برای Gradle ایجاد بشه و با هربار Build نیاز نباشه دوباره این پروسه ایجاد بشه که خودش باعث میشه سرعت Build افزایش پیدا کنه. ضمن اینکه در تنظیمات بعدی میتونیم منابع مصرفی این پروسه رو افزایش بدیم تا باز هم سرعت Build افزایش پیدا کنه.
  • org.gradle.jvmargs=-Xmx2048M: در این خط میتونیم پارامترهای معتبر JVM رو وارد کنیم. تنظیماتی که اینجا انجام گرفته، به Gradle daemon به میزان ۲ گیگ رم اختصاص میده که باعث افزایش سرعت Build میشه. البته حواستون باشه که سیستمتون باید به اندازه ی کافی رم داشته باشه (به همین دلیل توصیه می کنم سیستمی که واسه اینکار استفاده می کنید حداقل ۸ گیگ رم داشته باشه)
  • org.gradle.configureondemand=true: این خط بیشتر برای پروژه هایی که از چندین ماژول تشکیل شدن معنی پیدا می کنه و درواقع تنها درصورتی هرکدوم از پروژه ها رو Configure می کنه که بهشون نیاز باشه. شاید برای پروژه های معمولی تاثیر مثبتی نداشته باشه.
  • org.gradle.parallel=true: این خط هم ظاهراً باعث میشه در پروژه هایی که از چند تشکیل شدن (چند ماژول)، عملیات کانفیگ این پروژه ها رو بصورت موازی انجام بده که سرعت Build رو افزایش میده. این حالت هم ظاهراً برای پروژه های چند بخشی تاثیر بیشتری داره.

 

استفاده از مجموعه ی این تنظیمات باعث شده من سرعت Build بیشتری داشته باشم. شاید برای شما هم مفید واقع بشه.

 

درصورتی که از این تنظیمات استفاده می کنید، ممنون میشم تاثیرش رو در سرعت Build روی سیستم خودتون (با ذکر مشخصات سیستم و سیستم عامل مورداستفاده) کامنت کنید.

  • Nevercom

کتابخانه ای که برای مدیریت درگاه بانکی در شرکت ازش استفاده می کردیم، مشکلاتی داشت و خیلی ازش راضی نبودیم.

یکی از مشکلات عمده ی این کتابخانه این بود که خیلی استاندارد نوشته نشده بود (و البته قدیمی بود) که اضافه کردن درگاه های دیگه رو دشوار می کرد.

 

از همون ابتدای بازنویسی سیستم ارائه ی محصول شرکت قصد داشتم که این ماژول رو تغییر بدم، اما بخاطر حجم کارهایی که باید انجام می شد، این موضوع به حاشیه رفت، چون به هرحال کار میکرد.

 

این اواخر متوجه شدم که این کتابخانه که برای مدیریت درگاه "به پرداخت ملت" ازش استفاده میکردیم مشکلاتی داره، به همین دلیل تلاش کردم که یک کتابخانه ی جایگزین پیدا کنم. اما متاسفانه جستجوی من نتیجه ای نداشت. من به کتابخانه ای نیاز داشتم که استاندارد نوشته شده باشه و از درگاه های متفاوتی پشتیبانی کنه، یا حداقل سازوکارش به گونه ای باشه که بشه راحت تر درگاه های جدید رو بهش اضافه کرد.

 

به دلیل اینکه نتونستم کتابخانه ی جایگزینی پیدا کنم (شاید وجود داشته باشه، و منطقاً می بایست وجود داشته باشه !)، دست به کار شدم و خودم شروع به نوشتنش کردم.

 

ایده ی من این بود که این کتابخانه باید کارکرد ساده ای داشته باشه و تا حد ممکن ماژولار طراحی بشه تا استفاده از درگاه های دیگه رو راحت کنه و بشه به راحتی درگاه های جدید رو بهش اضافه کرد (بیشتر از همه، خودم از این متنفرم که هربار برای اضافه کردن درگاه جدید، کل کدهام رو تغییر بدم).

 

نتیجه، کتابخانه ی مدیریت درگاه های بانکی ایران هست که در گیت هاب در دسترس هست:

  • Nevercom

سلام

 

برای ایجاد ارتباطی امن بین کلاینت ها و سرورتون، باید از SSL استفاده کنید. گاهی وقت ها مجبورید برای استفاده از خدماتی خاص، SSL رو برای اون دامین بخصوص فعال کنید، بعنوان مثال برای ارتباط با درگاه های بانکی خاص یا ساخت روبات تلگرام.

 

برای اینکار باید گواهینامه‌ی SSL (یا SSL Certificate) رو از سایت های معتبری که این خدمات رو ارائه میدن تهیه کنید، که بدون هزینه هم نخواهد بود.

در این بین سایت هایی هستند که این خدمات رو بصورت رایگان ارائه میدن، یکی از این سایت ها StartSSL هست که این مجوز رو بصورت رایگان به شما میده (گمان میکنم برای سال اول رایگان هست)

البته توجه داشته باشید که دامنه ی ir رو پشتیبانی نمیکنن و برای این دامین SSL رایگان ارائه نمیدن.

 

در این پست قصد دارم مراحل تهیه ی SSL و فعال سازی برای اون دامین رو روی یک سرور لینوکسی و تحت وب سرور Nginx اموزش بدم.

  • Nevercom

من از PHPStorm 8 برای برنامه نویسی PHP و Android Studio برای اندروید استفاده می کنم.

 

ادیتورهای خانواده ی IntelliJ IDEA رو بسیار دوست دارم، در نسخه ی PHPStorm 8  قابلیت Multiple Selection معرفی شد.

اگر از Sublime Text استفاده کرده باشید، میدونید که یکی از محبوب ترین قابلیت هاش، قابلیت Multiple Selection هست که به شما اجازه میده چندین Caret (یا Cursor - نشانگر موس) در نقاط مختلف صفحه داشته باشید و درواقع چند نقطه رو همزمان ویرایش کنید.

 

در PHPStorm این قابلیت با نگه داشتن Alt و Mouse Left Click در نقاط مختلف فعال میشه. مشکل اینجاست که در Ubuntu ترکیب Alt+Button1 برای حرکت دادن پنجره تعریف شده و با ترکیب کلید IDEA تداخل ایجاد می کنه.

 

دو راه وجود داره، یا اینکه ترکیب رو در IDEA تغییر بدید و یا اینکه ترکیب مربوطه رو در Ubuntu غیرفعال کنید.

 

از اونجایی که پیدا کردن ترکیب مناسب برای جایگزین کردن در IDEA سخته (Ctrl, Shift و ترکیبی از اینها به همراه کلیک ماوس رجیستر شدن و قابلیت هاشون رو نیاز دارم)، تصمیم گرفتم در سیستم این ترکیب رو غیرفعال کنم، چون نیازی هم بهش ندارم.

 

مثل همیشه با جستجویی در Google و AskUbuntu به پاسخ سوال می رسیم.

 

در دو بخش ترکیب Alt با Mouse Button رجیستر شده

  1. در تنظیمات پلاگین Move Window مربوط به Compiz
  2. دیگری در کلید org.gnome.desktop.wm.preferences.mouse-button-modifier 

اول تنظیمات Compiz رو تغییر میدیم، برای اینکار باید Compiz Config Settings Manager رو نصب کنید (sudo apt-get install compizconfig-settings-manager)، پلاگین Move Window رو پیدا کنید و شورت‌کاتی که ترکیب ALT>Button1> رو داره رو غیرفعال کنید.

 

حالا برید تو PHPStorm چک کنید ترکیب کلید Alt+Button1 (درواقع Alt رو نگه دارید و جاهای مختلف ادیتور Left Click کنید) جواب میده یا نه.

 

اگر مثل من متوجه شدید هنوز مشکل پابرجاست، یه کار دیگه هست که میتونید بکنید

روش دوم اعمال تغییر در dconf-editor هست

 

 

dconf-editor رو اجرا کنید، Ctrl+F رو بزنید تا کادر جستجو باز بشه و عبارت mouse-button-modifier رو جستجو کنید.

کلید موردنظر که پیدا شد مقدارش رو از <ALT> به <Super> تغییر بدید.

 

 

الان باید ترکیب Alt+Click در PHPStorm فعال شده باشه.

 

 

منبع: http://askubuntu.com/q/151252/107348

  • Nevercom

مدتها پیش در پستی جداگانه Parse SDK رو برای راه اندازی Push Notification در اندروید معرفی کرده بودم، دوست داشتم که آموزشی رو برای این ابزار فوق العاده معرفی کنم که فرصتش نمیشد.

 

بارها دوستان چه از طریق ایمیل، وبلاگ و انجمن برنامه نویس درخواست کردن که آموزشی رو برای این ابزار تهیه کنم.

بالاخره فرصت شد و ویدئویی رو برای راه اندازی قابلیت Push Notification توسط Parse SDK برای Android تهیه کردم.

 

در این ویدئو مطالب زیر شرح داده شده:

  • ایجاد App در سایت Parse.com و دریافت API Key و Client Key
  • آماده سازی اولیه اپلیکیشن اندروید برای استفاده از این سرویس
    • دسترسی های موردنیاز
    • تعریف بخش های موردنیاز در Manifest.xml
    • ایجاد کلاس Application و معرفی اون به مانیفست
    • راه اندازی Parse در کلاس Application
  • شخصی سازی رفتار Parse هنگام دریافت Push توسط BroadcastReceiver شخصی
    • عدم نمایش Notification بهنگام در یافت Push
  • باز شدن آدرس URI خاص هنگام کلیک روی Notification (مثلاً باز شدن اپ شما در بازار)

 

این آموزش با نسخه ی 1.7.1 Parse SDK ساخته شده

 

همچنین در BroadcastReceiver اختصاصی (منظور کلاسی هست که از ParsePushBroadcastReceiver مشتق شده و برای شخصی سازی رفتار Parse استفاده میشه)، کدهایی درج شده که برای اصلاح باگ موجود در این نسخه از SDK هست که هنگام دریافت Push، در صورتی که uri تعریف نشده باشه، اپلیکیشن کرش می کنه (البته در ویدئو این کدها هنوز نوشته نشدن و دیده نمیشن)

 

لینک دانلود سورس کد و دانلود مستقیم ویدئو در انتهای پست موجود هست (برای نمایش با کیفیت اصلی فایل ویدئو رو دانلود کنید)

  • Nevercom

من قابلیت Global Menu در  Unity رو خیلی دوست دارم، میاد منوها رو در پنل بالایی ادغام می کنه که باعث میشه فضای کاری بیشتری داشته باشیم. در نسخه ی 14.04 اوبونتو هم این قابلیت بهبود پیدا کرد و بعنوان یک آپشن، وقتی برنامه فول اسکرین نیست منو ها در تایتل بار ادغام میشن.

 

این افزایش فضای کاری بخصوص در IDE ها بکار میان که ادیتور باید فضای زیادی داشته باشه و علاوه بر اون Toolbar ها و Tab ها هم فضایی رو اشغال می کنن.

من از ۳ IDE استفاده  می کنم: NetBeans, Eclipse و خانواده ی IDE های JetBrains ( از جمله PhpStorm, IntelliJ IDEA و  Android Studio)

هر سه ی این  IDE ها توسط جاوا نوشته شدن و همه ی برنامه های جاوا از Global Menu نمیتونن استفاده کنن.

 

قبلاً در پستی روش فعال کردن این قابلیت برای NetBeans رو شرح داده بودم، اما می تونید با نصب یک پکیج این قابلیت رو برای بیشتر برنامه های جاوا فعال کنید.

 

sudo add-apt-repository ppa:danjaredg/jayatana
sudo apt-get update
sudo apt-get install jayatana

 

منبع: 

  • Nevercom

 

این مطلب رو چندماه پیش نوشته بودم، اما منتشرش نکردم، دلیلش این بود که قصد داشتم فقط ابزار رو معرفی نکرده باشم و همه ی قابلیت های این فریم وورک رو در قالب یک یا چند اپلیکیشن اندروید نمایش بدم، اما متاسفانه فرصتش پیش نیومد و تصمیم گرفتم همین مطلب رو منتشر کنم.

این اواخر در یکی از پروژه های اندروید نیاز به استفاده از قابلیت Push Notification داشتم، برای اندروید Google Cloud Messaging یا GCM موجود هست که بسیار هم قدرتمند هست، اما پیاده سازی اون (برای بار اول) کمی زمانبر هست و من فرصت کافی نداشتم.

دنبال یک فریم ورک خوب برای Push Notification بودم که با Parse SDK آشنا شدم.

من بنا به نیازم فقط از قابلیت Push Notification ش استفاده کردم اما قابلیت ها و توانایی های گسترده ی این SDK اون رو تبدیل به یک ابزار مناسب برای توسعه دهندگان نرم افزار می‌کنه. (و بخصوص توسعه دهندگان بدون پشتوانه ی مالی و دانش فنی برای اجاره و مدیریت سرور برای Backend نرم افزار)

 

  • Nevercom

قابلیت Unity Global Menu در اوبونتو رو خیلی دوست دارم، این قایلست باعث میشه که منو های برنامه ها همه در پنل بالایی نمایش داده بشن و نه در خود پنجره. این قابلیت علاوه بر افزایش فضای کاری (بخصوص در IDEها برای من اهمیت زیادی داره این مورد)، باعث یکپارچگی بیشتر سیستم عامل (از لحاظ بصری و اکوسیستم) میشه.

 

IDE محبوب من برای PHP نرم افزار Netbeans هست. بصورت پیشفرض Netbeans از قابلیت Global Menu استفاده نمیکنه و منوها در پنجره ی برنامه نمایش داده میشن:

 

 

برای اضافه کردن این قابلیت می تونید از پلاگین Ayatana استفاده کنید.

  • Nevercom

بعضی وقتا نیاز هست که یک عملیاتی در اولین اجرای اکتیویتی (Activity) صورت بگیره، بعنوان مثال در شرایطی که قصد دارید برای اولین بار یک راهنما رو در اکتیویتی نشون بدید.

 

اولین روشی که به ذهنتون خواهد رسید استفاده از SharedPreferences هست. SharedPreferences روشی ساده و کم هزینه برای ذخیره‌ی تنظیمات برنامه هست.

 

این تکه کد کلیدی حاوی داده ای از جنس Boolean در SharedPreferences ذخیره می‌کنه، درصورتی که کلید وجود نداشته باشه مقدار true رو برمی‌گردونه و درصورت وجود، مقدار واقعی ذخیره شده در این کلید.

SharedPreferences settings = getSharedPreferences("MY_PREFERENCES", 0);
final boolean ret = settings.getBoolean("activity.firstVisit", true);

if (ret) {
    Editor editor = settings.edit();
    editor.putBoolean("activity.firstVisit", false);
    editor.commit();
    
    // FIRST TIME
    // YOUR CODES GOES HERE
}

 

اگر فقط در یک اکتیویتی نیاز به چک کردن این موضوع داشته باشید، همین روش استفاده شده مناسب هست و شلوغی زیادی هم نداره

اما اگر نیاز باشه در چندین اکتیویتی مختلف این موضوع بررسی بشه و بر اساس اون عملیاتی انجام بشه میشه کدها رو مرتب تر کرد و از شلوغی کدها جلوگیری کرد

  • Nevercom