الفرق بين المراجعتين لصفحة: «Cordova/plugins ios»

من موسوعة حسوب
لا ملخص تعديل
لا ملخص تعديل
سطر 100: سطر 100:
== انظر أيضا==
== انظر أيضا==
*[[Cordova/plugins android|إضافات أندرويد]]
*[[Cordova/plugins android|إضافات أندرويد]]
*[[plugins windows|إضافات ويندوز]]
*[[Cordova/plugins windows|إضافات ويندوز]]


*صفحة [[Cordova/plugins|دليل تطوير الإضافات]]
*صفحة [[Cordova/plugins|دليل تطوير الإضافات]]
==مصادر==
==مصادر==
*[https://cordova.apache.org/docs/en/latest/guide/platforms/ios/plugin.html صفحة iOS Plugin Development Guide في توثيق كوردوفا الرسمي.]
*[https://cordova.apache.org/docs/en/latest/guide/platforms/ios/plugin.html صفحة iOS Plugin Development Guide في توثيق كوردوفا الرسمي.]

مراجعة 16:23، 23 نوفمبر 2018

يقدم هذا القسم تفاصيل عن كيفية تقديم (implement) شيفرات الإضافات الأصلية (native plugin code) على منصة iOS. قبل قراءة هذه الصفحة، راجع صفحة دليل تطوير الإضافات للحصول على نظرة عامة على بنية الإضافات وواجهة جافاسكريبت الخاصة بها.

يواصل هذا القسم تطوير مثال الإضافة echo الوارد في دليل تطوير الإضافات، والذي يربط الاتصال بين المعرض webview والمنصة الأصلية (native platform).

يتم تقديم (implement) إضافات iOS على هيئة صنف من لغة ‏‎ ‏‎Objective-C‎‎، والذي يوسع الصنف CDVPlugin.

لكي يُربط الوسيط service المُمرر إلى التابع exec مع صنف في لغة Objective-C، فيجب تسجيل كل أصناف الإضافة على هيئة وسم <feature> في الملف config.xml.

إعداد صنف الإضافة

يُستخدم الجزء من الإضافة المكتوب بلغة جافاسكريبت التابعَ cordova.exec على النحو التالي:

exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);

هذا سيُرسل طلبية (request) من UIWebView إلى الجانب الأصلي (native side) من منصة iOS، ثم يستدعي التابع action على الصنف service فعلياً، مع تمرير الوسائط المعطاة في المصفوفة args. قم بحديد الإضافة على هيئة وسم <feature> في الملف config.xml الخاص بتطبيق Cordova-iOS، مع استخدام الملف plugin.xml لإدراج هذا الوسم تلقائيًا، كما هو موضح في دليل تطوير الإضافات:

<feature name="LocalStorage">
    <param name="ios-package" value="CDVLocalStorage" />
</feature>

يجب أن تتطابق الخاصية name في الوسم feature مع قيمة الوسيط service الذي مررته سابقا إلى دالة جافاسكريبت exec . كما يجب أن تتطابق الخاصية value مع اسم صنف الإضافة في Objective-C. ويجب أن تساوي الخاصية name في الوسم <param> دائمًا القيمة "ios-package".

إذا لم تتبع هذه الإرشادات، فقد يتم تصريف (compile) الإضافة، ولكن قد لا تتمكن كوردوفا من الوصول إليها.

تهيئة الإضافات ودورة الحياة (Plugin Initialization and Lifetime)

يتم إنشاء نسخة (instance) واحدة من كائن الإضافة خلال دورة حياة المعرض UIWebView. لا يتم إنشاء نسخ للإضافات حتى تتم الإشارة إليها أولاً عبر استدعاء من جافاسكريبت، إلا في حال إضافة الوسم <param>، مع الخاصيتين name="onload"‎ و value="true"‎في الملف config.xml على النحو التالي:

<feature name="Echo">
    <param name="ios-package" value="Echo" />
    <param name="onload" value="true" />
</feature>‎

يجب أن تستخدم الإضافاتُ التابع pluginInitialize في مرحلة الانطلاق (startup logic).

لإضافات الطلبيات الطويلة (long-running requests)، أو النشاطات الخلفية (background activity)، مثل قارئات الوسائط، أو المستمعات (listeners)، أو النشاطات ذات الحالة الداخلية (internal state) يجب أن تقوم بتقدِيم (implement) التابع onReset لأجل إلغاء تلك الطلبيات الطويلة، أو للتنظيف بعد تلك الأنشطة. يتم تشغيل التابع onReset عند انتقال UIWebView إلى صفحة جديدة أو عند تحديث الصفحة، وهو ما يؤدي إلى إعادة تحميل جافاسكريبت.

كتابة إضافات iOS

يرسل استدعاء جافاسكريبت (JavaScript call) طلبية إضافة (plugin request) إلى الجانب الأصلي (native side)، وتُعيّن إضافة Objective-C المقابلة في الملف config.xml. وأي شيء يتم إرساله إلى الإضافة عبر الدالة exec سيُمرّر إلى التابع action الخاص بصنف بالإضافة.

فيما يلي إمضاء (signature) تابع الإضافة:

- (void)myMethod:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* pluginResult = nil;
    NSString* myarg = [command.arguments objectAtIndex:0];
    if (myarg != nil) {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    } else {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Arg was null"];
    }
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

لمزيد من التفاصيل، راجع الصفحات CDVInvokedUrlCommand.h و CDVPluginResult.h و CDVCommandDelegate.h.

أنواع الرسائل CDVPluginResult في منصة iOS

يمكنك استخدام CDVPluginResult لإعادة مجموعة متنوعة من أنواع النتائج إلى استدعاءات جافاسكريبت، باستخدام توابع تتبع النمط التالي:

+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAs...

يمكنك إنشاء الأنواع String و Int و Double و Bool و Array و Dictionary و ArrayBuffer و Multipart. يمكنك أيضًا استبعاد أي وسيط لأجل إرسال حالة، أو لإعادة خطأ، أو يمكنك حتى اختيار عدم إرسال أي نتيجة للإضافة، وفي هذه الحالة لن يُطلق أيٌّ من تلك الاستدعاءات.

تذكر ما يلي عند التعامل مع القيم المعادة المعقدة:

  • messageAsArrayBuffer تتوقع NSData*‎، وتحوله إلى ArrayBuffer في استدعاء جافاسكريبت. وبالمثل، أي كائن ArrayBuffer ترسله جافاسكريبت إلى الإضافة سيُحوّل إلى NSData*‎.
  • messageAsMultipart تتوقع مصفوفة NSArray*‎ تحتوي على أيٍّ من الأنواع المدعومة الأخرى، وترسل المصفوفة بأكملها باعتبارها الوسيطarguments إلى استدعاء جافاسكريبت (JavaScript callback). بهذه الطريقة، تُسلسل (serialized) كل الوسائط أو تُفلّ (deserialized) بحسب الضرورة، لذلك من الآمن إعادة NSData*‎ كسلسلة متعددة (multipart)، ولكن ليس على هيئة مصفوفة أو قاموس.

مثال لإضافة iOS

لمطابقة واجهة الميزة echo المقدمة في صفحة الإضافات، استخدم الملف plugin.xml لإدراج مواصفات feature في الملف config.xml الخاص بالمنصة المحلية:

<platform name="ios">
    <config-file target="config.xml" parent="/*">
        <feature name="Echo">
            <param name="ios-package" value="Echo" />
        </feature>
    </config-file>
</platform>‎

ثم أضف الملفين Echo.h و Echo.m إلى المجلد Plugins الموجود في مجلد تطبيق Cordova-iOS:

/********* Echo.h Cordova Plugin Header *******/
#import <Cordova/CDVPlugin.h>

@interface Echo : CDVPlugin
- (void)echo:(CDVInvokedUrlCommand*)command;
@end
/********* Echo.m Cordova Plugin Implementation *******/
#import "Echo.h"
#import <Cordova/CDVPlugin.h>

@implementation Echo
- (void)echo:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* pluginResult = nil;
    NSString* echo = [command.arguments objectAtIndex:0];
    if (echo != nil && [echo length] > 0) {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
    } else {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    }
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@end

تُوسّع عمليات الاستيراد (import) في الجزء العلوي من الملف الصنفَ CDVPlugin. في هذه الحالة، لا تدعم الإضافة سوى إجراء (action) واحد، وهوecho. تُستخلص السلسلة النصية echo عن طريق استدعاء التابع objectAtIndex للحصول على الوسيط الأول الموجود في المصفوفة arguments، والذي يتوافق مع الوسائط المُمررة من قبل دالة جافاسكريبت exec()‎.

تتحقق الشيفرة من أن الوسيط لا يساوي القيمة nil أو سلسلة نصية فارغة، فإن كان الأمر كذلك فستعيد PluginResult مع الحالة "ERROR". وإلا فستعيد PluginResult مع الحالة "OK"، مع تمرير السلسلة النصية الأصلية echo. وأخيرًا، تُرسل النتيجة إلى التابع self.commandDelegate، والذي ينفذ دوال النجاح أو الإخفاق (success or failure callbacks) الخاصة بالتابع exec على جانب جافاسكريبت. في حال استدعاء دالة النجاح، فسيُمرر إليها الوسيط echo.

التكامل مع منصة iOS

يوفر الصنف CDVPlugin توابع أخرى يمكن إعادة تعريفها من قبل الإضافة. على سبيل المثال، يمكنك إمساك الأحداث pause و resume و إنهاء التطبيق (app terminate) و handleOpenURL. راجع الصنفين CDVPlugin.h و CDVPlugin.m لأجل الإرشادات.

المهام الفرعية (Threading)

تنفّذ توابع الإضافة عادةً في نفس المهمة الفرعية التي تشتغل عليها الواجهة الرئيسية. إن كانت الإضافة تتطلب قدرًا كبيرًا من المعالجة، أو تتطلب القيام باستدعاء مُعطِّل (blocking call)، فعليك استخدام مهمة فرعية خلفية (background thread). مثلا:

- (void)myPluginMethod:(CDVInvokedUrlCommand*)command
{
    // هنا command.arguments تحقق من
    [self.commandDelegate runInBackground:^{
        NSString* payload = nil;
        // Some blocking logic...
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
        // آمن في المهام الفرعية sendPluginResult  استخدام
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }];
}

تصحيح إضافات iOS ‏(Debugging iOS Plugins‏)

لتصحيح الأخطاء في شيفرة Objective-C، سيكون عليك استخدام المُصحِّح المدمج في Xcode. أما بالنسبة إلى جافاسكريبت، فيمكنك ربط Safari بالتطبيق عبر محاكي أو جهاز iOS.

أخطاء شائعة

  • لا تنسَ إدراج خريطة الإضافة (plugin's mapping) إلى الملف config.xml. وإلا فسيُسجّل خطأ في وحدة تحكم Xcode.
  • لا تنس إضافة كل المضيفات التي تتصل بها في القائمة البيضاء. وإلا فسيُسجّل خطأ في وحدة تحكم Xcode.

 انظر أيضا

مصادر