كيفية استخدام العميل المدار لتطبيقات Azure للأجهزة المحمولة

نظرة عامة

يوضح لك هذا الدليل كيفية تنفيذ السيناريوهات الشائعة باستخدام مكتبة العميل المدارة لتطبيقات الأجهزة المحمولة لخدمة تطبيقات Azure App Service للأجهزة المحمولة Windows وXamarin. إذا كنت جديدا على تطبيقات الجوال، فيجب أن تفكر أولا في إكمال البرنامج التعليمي للتشغيل السريع لتطبيقات Azure للأجهزة المحمولة . في هذا الدليل ، نركز على SDK المدارة من جانب العميل. لمعرفة المزيد حول مجموعات تطوير البرامج (SDK) من جانب الخادم لتطبيقات الأجهزة المحمولة، راجع الوثائق الخاصة ب . NET Server SDK أو حزمة SDK لخادمNode.js.

الوثائق المرجعية

توجد الوثائق المرجعية لحزمة SDK الخاصة بالعميل هنا: مرجع عميل Azure Mobile Apps .NET. يمكنك أيضا العثور على العديد من عينات العميل في مستودع Azure-Samples GitHub.

المنصات المدعومة

يدعم النظام الأساسي .NET الأنظمة الأساسية التالية:

  • إصدارات Xamarin Android لواجهة برمجة التطبيقات من 19 إلى 24 (KitKat من خلال Nougat)
  • إصدارات Xamarin iOS لإصدارات iOS 8.0 والإصدارات الأحدث
  • النظام الأساسي العام لـ Windows
  • Windows Phone 8.1
  • Windows Phone 8.0 باستثناء تطبيقات Silverlight

تستخدم مصادقة "تدفق الخادم" WebView لواجهة المستخدم المقدمة. إذا لم يتمكن الجهاز من تقديم واجهة مستخدم WebView ، فهناك حاجة إلى طرق أخرى للمصادقة. وبالتالي فإن حزمة SDK هذه ليست مناسبة للأجهزة من نوع Watch أو الأجهزة المقيدة بشكل مماثل.

الإعداد والمتطلبات الأساسية

نفترض أنك قمت بالفعل بإنشاء ونشر مشروع الواجهة الخلفية لتطبيق الجوال، والذي يتضمن جدولا واحدا على الأقل. في التعليمة البرمجية المستخدمة في هذا الموضوع، يتم تسمية TodoItem الجدول ويحتوي على الأعمدة التالية: Id، ، Textو Complete. هذا الجدول هو نفس الجدول الذي تم إنشاؤه عند إكمال التشغيل السريع لتطبيقات Azure للأجهزة المحمولة.

النوع المكتوب المقابل من جانب العميل في C # هو الفئة التالية:

public class TodoItem
{
    public string Id { get; set; }

    [JsonProperty(PropertyName = "text")]
    public string Text { get; set; }

    [JsonProperty(PropertyName = "complete")]
    public bool Complete { get; set; }
}

يتم استخدام JsonPropertyAttribute لتعريف تعيين PropertyName بين حقل العميل وحقل الجدول.

لمعرفة كيفية إنشاء جداول في الواجهة الخلفية لتطبيقات الجوال، راجع موضوع . NET Server SDK أو موضوع حزمة SDK لخادمNode.js. إذا قمت بإنشاء الواجهة الخلفية لتطبيق الجوال في مدخل Azure باستخدام QuickStart، فيمكنك أيضا استخدام إعداد الجداول السهلة في مدخل Azure.

كيفية القيام بما يلي: تثبيت حزمة SDK للعميل المدار

استخدم إحدى الطرق التالية لتثبيت حزمة SDK للعميل المدار لتطبيقات الجوال من NuGet:

  • Visual Studio انقر بزر الماوس الأيمن فوق مشروعك، انقر على إدارة حزم NuGet، وابحث عن Microsoft.Azure.Mobile.Client الحزمة، ثم انقر على تثبيت.
  • استوديو زامارين انقر بزر الماوس الأيمن فوق المشروع الخاص بك، انقر فوق إضافة>حزم NuGet، وابحث عن Microsoft.Azure.Mobile.Client الحزمة، ثم انقر فوق إضافة حزمة.

في ملف النشاط الرئيسي، تذكر إضافة ما يلي باستخدام العبارة:

using Microsoft.WindowsAzure.MobileServices;

ملاحظة

يرجى ملاحظة أن جميع حزم الدعم المشار إليها في مشروع Android الخاص بك يجب أن يكون لها نفس الإصدار. تعتمد SDK على Xamarin.Android.Support.CustomTabs النظام الأساسي لنظام Android الأساسي ، لذلك إذا كان مشروعك يستخدم حزم دعم أحدث ، فأنت بحاجة إلى تثبيت هذه الحزمة بالإصدار المطلوب مباشرة لتجنب التعارضات.

كيفية القيام بما يلي: العمل مع رموز تصحيح الأخطاء في Visual Studio

تتوفر رموز مساحة اسم Microsoft.Azure.Mobile على SymbolSource. ارجع إلى إرشادات SymbolSource لدمج SymbolSource مع Visual Studio.

إنشاء عميل تطبيقات الجوال

التعليمة البرمجية التالية بإنشاء كائن MobileServiceClient الذي يتم استخدامه للوصول إلى الواجهة الخلفية لتطبيق الجوال.

var client = new MobileServiceClient("MOBILE_APP_URL");

في التعليمة البرمجية السابقة، استبدل MOBILE_APP_URL بعنوان URL الخاص بالواجهة الخلفية لتطبيق الأجهزة المحمولة، والذي يوجد في الشفرة للواجهة الخلفية لتطبيق الجوال في مدخل Azure. يجب أن يكون كائن MobileServiceClient مفردا.

العمل باستخدام الجداول

يوضح القسم التالي بالتفصيل كيفية البحث عن السجلات واستردادها وتعديل البيانات داخل الجدول. يتم تناول المواضيع التالية:

كيفية القيام بما يلي: إنشاء مرجع جدول

تستدعي جميع التعليمات البرمجية التي تصل إلى البيانات الموجودة في جدول خلفي أو تعدلها وظائف على MobileServiceTable الكائن. الحصول على مرجع إلى الجدول عن طريق استدعاء الأسلوب GetTable كما يلي:

IMobileServiceTable<TodoItem> todoTable = client.GetTable<TodoItem>();

يستخدم الكائن الذي تم إرجاعه نموذج التسلسل المكتوب. كما يتم دعم نموذج تسلسل غير مكتوب. ينشئ المثال التالي مرجعا إلى جدول غير مكتوب:

// Get an untyped table reference
IMobileServiceTable untypedTodoTable = client.GetTable("TodoItem");

في الاستعلامات غير المكتوبة، يجب تحديد سلسلة استعلام OData الأساسية.

كيفية: الاستعلام عن البيانات من تطبيق الجوال الخاص بك

يوضح هذا القسم كيفية إصدار استعلامات إلى الواجهة الخلفية لتطبيق الجوال، والتي تتضمن الوظائف التالية:

ملاحظة

يتم فرض حجم صفحة يستند إلى الخادم لمنع إرجاع جميع الصفوف. يمنع ترحيل الصفحات الطلبات الافتراضية لمجموعات البيانات الكبيرة من التأثير سلبا على الخدمة. لإرجاع أكثر من 50 صفا، استخدم Skip الطريقة والطريقة Take ، كما هو موضح في إرجاع البيانات في الصفحات.

كيفية القيام بما يلي: تصفية البيانات التي تم إرجاعها

توضح التعليمة البرمجية التالية كيفية تصفية البيانات عن طريق تضمين Where جملة في استعلام. ترجع هذه الدالة كافة العناصر todoTable التي Complete تساوي خاصيتها false. تطبق الدالة Where مسند تصفية صف على الاستعلام مقابل الجدول.

// This query filters out completed TodoItems and items without a timestamp.
List<TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false)
    .ToListAsync();

يمكنك عرض عنوان URI للطلب المرسل إلى الواجهة الخلفية باستخدام برنامج فحص الرسائل، مثل أدوات مطوري المستعرض أو Fiddler. إذا نظرت إلى عنوان URI للطلب، فلاحظ أنه تم تعديل سلسلة الاستعلام:

GET /tables/todoitem?$filter=(complete+eq+false) HTTP/1.1

يتم ترجمة طلب OData هذا إلى استعلام SQL بواسطة حزمة SDK للخادم:

SELECT *
    FROM TodoItem
    WHERE ISNULL(complete, 0) = 0

يمكن أن تحتوي الدالة التي يتم تمريرها إلى الطريقة على Where عدد تعسفي من الشروط.

// This query filters out completed TodoItems where Text isn't null
List<TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false && todoItem.Text != null)
    .ToListAsync();

سيتم ترجمة هذا المثال إلى استعلام SQL بواسطة Server SDK:

SELECT *
    FROM TodoItem
    WHERE ISNULL(complete, 0) = 0
          AND ISNULL(text, 0) = 0

يمكن أيضا تقسيم هذا الاستعلام إلى جمل متعددة:

List<TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false)
    .Where(todoItem => todoItem.Text != null)
    .ToListAsync();

الطريقتان متساويتان ويمكن استخدامهما بالتبادل. الخيار الأول - وهو تسلسل مسندات متعددة في استعلام واحد - أكثر إحكاما ومستحسنا.

Where يدعم البند العمليات التي يجب ترجمتها إلى مجموعة OData الفرعية. وتشمل العمليات ما يلي:

  • العوامل العلائقية (==, !=, , =, , <<>>=),
  • عوامل التشغيل الحسابية (+, -, /, *, ٪),
  • دقة الأرقام (Math.Floor, Math.Roof),
  • وظائف السلسلة (الطول ، السلسلة الفرعية ، الاستبدال ، IndexOf، StartsWith، EndsWith)،
  • خصائص التاريخ (السنة ، الشهر ، اليوم ، الساعة ، الدقيقة ، الثانية) ،
  • خصائص الوصول إلى كائن، و
  • التعبيرات التي تجمع بين أي من هذه العمليات.

عند النظر في ما تدعمه حزمة SDK للخادم، يمكنك النظر في وثائق OData v3.

كيفية القيام بما يلي: فرز البيانات التي تم إرجاعها

توضح التعليمة البرمجية التالية كيفية فرز البيانات عن طريق تضمين دالة OrderBy أو OrderByDescending في الاستعلام. يقوم بإرجاع العناصر من todoTable فرز تصاعدي حسب الحقل Text .

// Sort items in ascending order by Text field
MobileServiceTableQuery<TodoItem> query = todoTable
                .OrderBy(todoItem => todoItem.Text)
List<TodoItem> items = await query.ToListAsync();

// Sort items in descending order by Text field
MobileServiceTableQuery<TodoItem> query = todoTable
                .OrderByDescending(todoItem => todoItem.Text)
List<TodoItem> items = await query.ToListAsync();

كيفية القيام بما يلي: إرجاع البيانات في الصفحات

بشكل افتراضي، ترجع الواجهة الخلفية أول 50 صفا فقط. يمكنك زيادة عدد الصفوف التي تم إرجاعها عن طريق استدعاء طريقة أخذ . استخدم Take مع طريقة تخطي لطلب "صفحة" معينة من إجمالي مجموعة البيانات التي تم إرجاعها بواسطة الاستعلام. يرجع الاستعلام التالي، عند تنفيذه، العناصر الثلاثة الأولى في الجدول.

// Define a filtered query that returns the top 3 items.
MobileServiceTableQuery<TodoItem> query = todoTable.Take(3);
List<TodoItem> items = await query.ToListAsync();

يتخطى الاستعلام المنقح التالي النتائج الثلاث الأولى ويقوم بإرجاع النتائج الثلاث التالية. ينتج هذا الاستعلام "الصفحة" الثانية من البيانات، حيث يكون حجم الصفحة ثلاثة عناصر.

// Define a filtered query that skips the top 3 items and returns the next 3 items.
MobileServiceTableQuery<TodoItem> query = todoTable.Skip(3).Take(3);
List<TodoItem> items = await query.ToListAsync();

تطلب الأسلوب IncludeTotalCount العدد الإجمالي لكافة السجلات التي كان سيتم إرجاعها، متجاهلة أي بند ترحيل/حد محدد:

query = query.IncludeTotalCount();

في تطبيق العالم الحقيقي، يمكنك استخدام استعلامات مشابهة للمثال السابق مع عنصر تحكم جهاز النداء أو واجهة مستخدم مماثلة للتنقل بين الصفحات.

ملاحظة

لتجاوز حد 50 صفا في الواجهة الخلفية لتطبيق الجوال، يجب عليك أيضا تطبيق EnableQueryAttribute على أسلوب GET العام وتحديد سلوك ترحيل الصفحات. عند تطبيقه على الطريقة، يقوم ما يلي بتعيين الحد الأقصى للصفوف التي تم إرجاعها إلى 1000:

[EnableQuery(MaxTop=1000)]

كيفية القيام بما يلي: تحديد أعمدة معينة

يمكنك تحديد مجموعة الخصائص التي تريد تضمينها في النتائج عن طريق إضافة عبارة تحديد إلى الاستعلام. على سبيل المثال، توضح التعليمة البرمجية التالية كيفية تحديد حقل واحد فقط وكذلك كيفية تحديد حقول متعددة وتنسيقها:

// Select one field -- just the Text
MobileServiceTableQuery<TodoItem> query = todoTable
                .Select(todoItem => todoItem.Text);
List<string> items = await query.ToListAsync();

// Select multiple fields -- both Complete and Text info
MobileServiceTableQuery<TodoItem> query = todoTable
                .Select(todoItem => string.Format("{0} -- {1}",
                    todoItem.Text.PadRight(30), todoItem.Complete ?
                    "Now complete!" : "Incomplete!"));
List<string> items = await query.ToListAsync();

جميع الوظائف الموصوفة حتى الآن مضافة ، حتى نتمكن من الاستمرار في تسلسلها. تؤثر كل مكالمة متسلسلة على المزيد من الاستعلام. مثال آخر:

MobileServiceTableQuery<TodoItem> query = todoTable
                .Where(todoItem => todoItem.Complete == false)
                .Select(todoItem => todoItem.Text)
                .Skip(3).
                .Take(3);
List<string> items = await query.ToListAsync();

كيفية القيام بما يلي: البحث عن البيانات حسب المعرف

يمكن استخدام الدالة LookupAsync للبحث عن كائنات من قاعدة البيانات باستخدام معرف معين.

// This query filters out the item with the ID of 37BBF396-11F0-4B39-85C8-B319C729AF6D
TodoItem item = await todoTable.LookupAsync("37BBF396-11F0-4B39-85C8-B319C729AF6D");

كيفية: تنفيذ الاستعلامات غير المكتوبة

عند تنفيذ استعلام باستخدام كائن جدول غير مكتوب، يجب تحديد سلسلة استعلام OData بشكل صريح عن طريق استدعاء ReadAsync، كما في المثال التالي:

// Lookup untyped data using OData
JToken untypedItems = await untypedTodoTable.ReadAsync("$filter=complete eq 0&$orderby=text");

يمكنك استعادة قيم JSON التي يمكنك استخدامها مثل حقيبة الممتلكات. لمزيد من المعلومات حول Json.NET JToken و Newtonsoft ، راجع موقع Json.NET .

كيفية القيام بما يلي: إدراج بيانات في الواجهة الخلفية لتطبيق الجوال

يجب أن تحتوي جميع أنواع العملاء على عضو يسمى Id، وهو عبارة عن سلسلة بشكل افتراضي. هذا المعرف مطلوب لتنفيذ عمليات CRUD وللمزامنة في وضع عدم الاتصال. توضح التعليمة البرمجية التالية كيفية استخدام الأسلوب InsertAsync لإدراج صفوف جديدة في جدول. تحتوي المعلمة على البيانات المراد إدراجها ككائن .NET.

await todoTable.InsertAsync(todoItem);

إذا لم يتم تضمين قيمة معرف مخصص فريد في أثناء الإدراج todoItem ، يتم إنشاء GUID بواسطة الخادم. يمكنك استرداد المعرف الذي تم إنشاؤه عن طريق فحص الكائن بعد عودة المكالمة.

لإدراج بيانات غير مكتوبة، يمكنك الاستفادة من Json.NET:

JObject jo = new JObject();
jo.Add("Text", "Hello World");
jo.Add("Complete", false);
var inserted = await table.InsertAsync(jo);

في ما يلي مثال على استخدام عنوان بريد إلكتروني كمعرف سلسلة فريد:

JObject jo = new JObject();
jo.Add("id", "myemail@emaildomain.com");
jo.Add("Text", "Hello World");
jo.Add("Complete", false);
var inserted = await table.InsertAsync(jo);

العمل مع قيم المعرف

تدعم تطبيقات الجوال قيم سلسلة مخصصة فريدة لعمود معرف الجدول. تسمح قيمة السلسلة للتطبيقات باستخدام قيم مخصصة مثل عناوين البريد الإلكتروني أو أسماء المستخدمين للمعرف. توفر لك معرفات السلسلة المزايا التالية:

  • يتم إنشاء المعرفات دون القيام برحلة ذهابا وإيابا إلى قاعدة البيانات.
  • من الأسهل دمج السجلات من جداول أو قواعد بيانات مختلفة.
  • يمكن أن تتكامل قيم المعرفات بشكل أفضل مع منطق التطبيق.

عندما لا يتم تعيين قيمة معرف سلسلة على سجل مدرج، تقوم الواجهة الخلفية لتطبيق الجوال بإنشاء قيمة فريدة للمعرف. يمكنك استخدام طريقة Guid.NewGuid لإنشاء قيم المعرف الخاصة بك ، إما على العميل أو في الواجهة الخلفية.

JObject jo = new JObject();
jo.Add("id", Guid.NewGuid().ToString("N"));

كيفية القيام بما يلي: تعديل البيانات في الواجهة الخلفية لتطبيق الجوال

توضح التعليمة البرمجية التالية كيفية استخدام أسلوب UpdateAsync لتحديث سجل موجود بنفس المعرف بمعلومات جديدة. تحتوي المعلمة على البيانات المراد تحديثها ككائن .NET.

await todoTable.UpdateAsync(todoItem);

لتحديث البيانات غير المكتوبة، يمكنك الاستفادة من Json.NET كما يلي:

JObject jo = new JObject();
jo.Add("id", "37BBF396-11F0-4B39-85C8-B319C729AF6D");
jo.Add("Text", "Hello World");
jo.Add("Complete", false);
var inserted = await table.UpdateAsync(jo);

id يجب تحديد حقل عند إجراء تحديث. تستخدم الواجهة الخلفية الحقل id لتحديد الصف المطلوب تحديثه. يمكن الحصول على الحقل id من نتيجة المكالمة InsertAsync . يتم رفع a ArgumentException إذا حاولت تحديث عنصر دون توفير القيمة id .

كيفية القيام بما يلي: حذف البيانات في الواجهة الخلفية لتطبيق الجوال

توضح التعليمة البرمجية التالية كيفية استخدام الأسلوب DeleteAsync لحذف مثيل موجود. يتم تعريف المثيل بواسطة الحقل الذي id تم تعيينه على todoItemملف .

await todoTable.DeleteAsync(todoItem);

لحذف البيانات غير المكتوبة، يمكنك الاستفادة من Json.NET كما يلي:

JObject jo = new JObject();
jo.Add("id", "37BBF396-11F0-4B39-85C8-B319C729AF6D");
await table.DeleteAsync(jo);

عند تقديم طلب حذف، يجب تحديد معرف. لا يتم تمرير الخصائص الأخرى إلى الخدمة أو يتم تجاهلها في الخدمة. عادة ما تكون nullنتيجة المكالمة DeleteAsync . يمكن الحصول على بطاقة الهوية المراد تمريرها من نتيجة المكالمة InsertAsync . يتم طرح A MobileServiceInvalidOperationException عند محاولة حذف عنصر دون تحديد الحقل id .

كيفية: استخدام التزامن المتفائل لحل النزاعات

قد يقوم عميلان أو أكثر بكتابة تغييرات على نفس العنصر في نفس الوقت. بدون اكتشاف التعارض، ستحل الكتابة الأخيرة محل أي تحديثات سابقة. يفترض التحكم المتفائل في التزامن أن كل معاملة يمكن أن ترتكب وبالتالي لا تستخدم أي قفل للموارد. قبل إجراء معاملة، يتحقق التحكم المتفائل في التزامن من عدم قيام أي معاملة أخرى بتعديل البيانات. إذا تم تعديل البيانات ، التراجع عن المعاملة الملتزمة.

تدعم تطبيقات الأجهزة المحمولة التحكم المتفائل في التزامن من خلال تعقب التغييرات التي تطرأ على كل عنصر باستخدام version عمود خاصية النظام المحدد لكل جدول في الواجهة الخلفية لتطبيق الجوال. في كل مرة يتم فيها تحديث سجل، تقوم تطبيقات الجوال بتعيين version الخاصية لهذا السجل إلى قيمة جديدة. أثناء كل طلب تحديث، version تتم مقارنة خاصية السجل المضمن مع الطلب بنفس الخاصية للسجل على الخادم. إذا كان الإصدار الذي تم تمريره مع الطلب لا يتطابق مع الواجهة الخلفية ، فإن مكتبة العميل تثير MobileServicePreconditionFailedException<T> استثناء. النوع المضمن مع الاستثناء هو السجل من الواجهة الخلفية التي تحتوي على إصدار الخوادم من السجل. يمكن للتطبيق بعد ذلك استخدام هذه المعلومات لتحديد ما إذا كان سيتم تنفيذ طلب التحديث مرة أخرى بالقيمة الصحيحة version من الواجهة الخلفية لتنفيذ التغييرات.

حدد عمودا على فئة الجدول لخاصية النظام version لتمكين التزامن المتفائل. على سبيل المثال:

public class TodoItem
{
    public string Id { get; set; }

    [JsonProperty(PropertyName = "text")]
    public string Text { get; set; }

    [JsonProperty(PropertyName = "complete")]
    public bool Complete { get; set; }

    // *** Enable Optimistic Concurrency *** //
    [JsonProperty(PropertyName = "version")]
    public string Version { set; get; }
}

تتيح التطبيقات التي تستخدم الجداول غير المكتوبة التزامن المتفائل Version عن طريق تعيين العلامة على الجدول على SystemProperties النحو التالي.

//Enable optimistic concurrency by retrieving version
todoTable.SystemProperties |= MobileServiceSystemProperties.Version;

بالإضافة إلى تمكين التزامن المتفائل ، يجب عليك أيضا التقاط الاستثناء MobileServicePreconditionFailedException<T> في التعليمات البرمجية الخاصة بك عند الاتصال ب UpdateAsync. حل التعارض عن طريق تطبيق الصحيح version على السجل المحدث واستدعاء UpdateAsync مع السجل الذي تم حله. توضح التعليمة البرمجية التالية كيفية حل تعارض كتابة بمجرد اكتشافه:

private async void UpdateToDoItem(TodoItem item)
{
    MobileServicePreconditionFailedException<TodoItem> exception = null;

    try
    {
        //update at the remote table
        await todoTable.UpdateAsync(item);
    }
    catch (MobileServicePreconditionFailedException<TodoItem> writeException)
    {
        exception = writeException;
    }

    if (exception != null)
    {
        // Conflict detected, the item has changed since the last query
        // Resolve the conflict between the local and server item
        await ResolveConflict(item, exception.Item);
    }
}


private async Task ResolveConflict(TodoItem localItem, TodoItem serverItem)
{
    //Ask user to choose the resolution between versions
    MessageDialog msgDialog = new MessageDialog(
        String.Format("Server Text: \"{0}\" \nLocal Text: \"{1}\"\n",
        serverItem.Text, localItem.Text),
        "CONFLICT DETECTED - Select a resolution:");

    UICommand localBtn = new UICommand("Commit Local Text");
    UICommand ServerBtn = new UICommand("Leave Server Text");
    msgDialog.Commands.Add(localBtn);
    msgDialog.Commands.Add(ServerBtn);

    localBtn.Invoked = async (IUICommand command) =>
    {
        // To resolve the conflict, update the version of the item being committed. Otherwise, you will keep
        // catching a MobileServicePreConditionFailedException.
        localItem.Version = serverItem.Version;

        // Updating recursively here just in case another change happened while the user was making a decision
        UpdateToDoItem(localItem);
    };

    ServerBtn.Invoked = async (IUICommand command) =>
    {
        RefreshTodoItems();
    };

    await msgDialog.ShowAsync();
}

لمزيد من المعلومات، راجع موضوع مزامنة البيانات دون اتصال في Azure Mobile Apps .

كيفية القيام بما يلي: ربط بيانات تطبيقات الجوال بواجهة مستخدم Windows

يوضح هذا القسم كيفية عرض كائنات البيانات التي تم إرجاعها باستخدام عناصر واجهة المستخدم في تطبيق Windows. ترتبط التعليمة البرمجية للمثال التالي بمصدر القائمة مع استعلام عن العناصر غير المكتملة. تقوم مجموعة MobileServiceCollection بإنشاء مجموعة ربط على دراية بتطبيقات الجوال.

// This query filters out completed TodoItems.
MobileServiceCollection<TodoItem, TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false)
    .ToCollectionAsync();

// itemsControl is an IEnumerable that could be bound to a UI list control
IEnumerable itemsControl  = items;

// Bind this to a ListBox
ListBox lb = new ListBox();
lb.ItemsSource = items;

تدعم بعض عناصر التحكم في وقت التشغيل المدار واجهة تسمى ISupportIncrementalLoading. تسمح هذه الواجهة لعناصر التحكم بطلب بيانات إضافية عند تمرير المستخدم. هناك دعم مدمج لهذه الواجهة لتطبيقات Windows العالمية عبر MobileServiceIncrementalLoadingCollection ، والذي يتعامل تلقائيا مع المكالمات من عناصر التحكم. استخدم MobileServiceIncrementalLoadingCollection في تطبيقات Windows على النحو التالي:

MobileServiceIncrementalLoadingCollection<TodoItem,TodoItem> items;
items = todoTable.Where(todoItem => todoItem.Complete == false).ToIncrementalLoadingCollection();

ListBox lb = new ListBox();
lb.ItemsSource = items;

لاستخدام المجموعة الجديدة على تطبيقات Windows Phone 8 و "Silverlight" ، استخدم طرق الإضافة ToCollection على IMobileServiceTableQuery<T> و IMobileServiceTable<T>. لتحميل البيانات، اتصل ب LoadMoreItemsAsync().

MobileServiceCollection<TodoItem, TodoItem> items = todoTable.Where(todoItem => todoItem.Complete==false).ToCollection();
await items.LoadMoreItemsAsync();

عند استخدام المجموعة التي تم إنشاؤها عن طريق الاتصال ToCollectionAsync أو ToCollection، تحصل على مجموعة يمكن ربطها بعناصر تحكم واجهة المستخدم. هذه المجموعة على دراية بالترحيل. نظرا لأن المجموعة تقوم بتحميل البيانات من الشبكة ، يفشل التحميل في بعض الأحيان. للتعامل مع مثل هذه الإخفاقات ، قم بتجاوز OnException الطريقة MobileServiceIncrementalLoadingCollection للتعامل مع الاستثناءات الناتجة عن المكالمات إلى LoadMoreItemsAsync.

ضع في اعتبارك ما إذا كان الجدول يحتوي على العديد من الحقول ولكنك تريد فقط عرض بعضها في عنصر التحكم الخاص بك. يمكنك استخدام الإرشادات الواردة في القسم السابق "تحديد أعمدة معينة" لتحديد أعمدة معينة لعرضها في واجهة المستخدم.

تغيير حجم الصفحة

تقوم تطبيقات Azure للأجهزة المحمولة بإرجاع 50 عنصرا كحد أقصى لكل طلب بشكل افتراضي. يمكنك تغيير حجم ترحيل الصفحات عن طريق زيادة الحد الأقصى لحجم الصفحة على كل من العميل والخادم. لزيادة حجم الصفحة المطلوبة، حدد PullOptions عند استخدام PullAsync():

PullOptions pullOptions = new PullOptions
    {
        MaxPageSize = 100
    };

بافتراض أنك حققت ما يساوي أو يزيد عن PageSize 100 داخل الخادم، يقوم الطلب بإرجاع ما يصل إلى 100 عنصر.

استخدام الجداول غير المتصلة بالإنترنت

تستخدم الجداول غير المتصلة بالإنترنت مخزن SQLite محلي لتخزين البيانات لاستخدامها في وضع عدم الاتصال. تتم كافة عمليات الجدول مقابل مخزن SQLite المحلي بدلا من مخزن الخادم البعيد. لإنشاء جدول غير متصل بالإنترنت، قم أولا بإعداد مشروعك:

  1. في Visual Studio، انقر بزر الماوس الأيمن فوق الحل إدارة حزم NuGet للحلول...، ثم ابحث عن حزمة Microsoft.Azure.Mobile.Client.SQLiteStore NuGet وتثبيتها لجميع المشاريع في الحل>.

  2. (اختياري) لدعم أجهزة Windows، قم بتثبيت إحدى حزم وقت تشغيل SQLite التالية:

  3. (اختياري). بالنسبة للأجهزة Windows، انقر فوق مراجعإضافة>مرجع...، وقم بتوسيع ملحقات المجلد > Windows، ثم قم بتمكين SQLite المناسب ل SDK Windows جنبا إلى جنب مع Visual C++ 2013 Runtime for Windows SDK. تختلف أسماء SQLite SDK قليلا مع كل Windows النظام الأساسي.

قبل إنشاء مرجع جدول، يجب إعداد المتجر المحلي:

var store = new MobileServiceSQLiteStore(Constants.OfflineDbPath);
store.DefineTable<TodoItem>();

//Initializes the SyncContext using the default IMobileServiceSyncHandler.
await this.client.SyncContext.InitializeAsync(store);

عادة ما تتم تهيئة المتجر مباشرة بعد إنشاء العميل. يجب أن يكون OfflineDbPath اسم ملف مناسب للاستخدام على جميع الأنظمة الأساسية التي تدعمها. إذا كان المسار مسارا مؤهلا بالكامل (أي أنه يبدأ بشرطة مائلة) ، استخدام هذا المسار. إذا لم يكن المسار مؤهلا بالكامل، وضع الملف في موقع خاص بالنظام الأساسي.

  • بالنسبة لأجهزة iOS و Android ، فإن المسار الافتراضي هو مجلد "الملفات الشخصية".
  • بالنسبة Windows الأجهزة، يكون المسار الافتراضي هو مجلد "AppData" الخاص بالتطبيق.

يمكن الحصول على مرجع جدول باستخدام GetSyncTable<> الطريقة:

var table = client.GetSyncTable<TodoItem>();

لا تحتاج إلى المصادقة لاستخدام جدول غير متصل بالإنترنت. تحتاج فقط إلى المصادقة عند التواصل مع خدمة الواجهة الخلفية.

مزامنة جدول غير متصل

لا تتم مزامنة الجداول غير المتصلة بالإنترنت مع الواجهة الخلفية بشكل افتراضي. تنقسم المزامنة إلى قطعتين. يمكنك دفع التغييرات بشكل منفصل عن تنزيل عناصر جديدة. فيما يلي طريقة مزامنة نموذجية:

public async Task SyncAsync()
{
    ReadOnlyCollection<MobileServiceTableOperationError> syncErrors = null;

    try
    {
        await this.client.SyncContext.PushAsync();

        await this.todoTable.PullAsync(
            //The first parameter is a query name that is used internally by the client SDK to implement incremental sync.
            //Use a different query name for each unique query in your program
            "allTodoItems",
            this.todoTable.CreateQuery());
    }
    catch (MobileServicePushFailedException exc)
    {
        if (exc.PushResult != null)
        {
            syncErrors = exc.PushResult.Errors;
        }
    }

    // Simple error/conflict handling. A real application would handle the various errors like network conditions,
    // server conflicts and others via the IMobileServiceSyncHandler.
    if (syncErrors != null)
    {
        foreach (var error in syncErrors)
        {
            if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
            {
                //Update failed, reverting to server's copy.
                await error.CancelAndUpdateItemAsync(error.Result);
            }
            else
            {
                // Discard local change.
                await error.CancelAndDiscardItemAsync();
            }

            Debug.WriteLine(@"Error executing sync operation. Item: {0} ({1}). Operation discarded.", error.TableName, error.Item["id"]);
        }
    }
}

إذا كانت الوسيطة PullAsync الأولى فارغة، فلن يتم استخدام المزامنة التدريجية. تقوم كل عملية مزامنة باسترداد جميع السجلات.

تقوم SDK بإجراء ضمني PushAsync() قبل سحب السجلات.

يحدث التعامل مع النزاعات على طريقة PullAsync() . يمكنك التعامل مع التعارضات بنفس طريقة التعامل مع الجداول عبر الإنترنت. يتم إنتاج التعارض عند PullAsync() استدعائه بدلا من أثناء الإدراج أو التحديث أو الحذف. في حالة حدوث تعارضات متعددة، يتم تجميعها في MobileServicePushFailedException واحد. تعامل مع كل فشل على حدة.

العمل باستخدام واجهة برمجة تطبيقات مخصصة

تمكنك واجهة برمجة التطبيقات المخصصة من تحديد نقاط النهاية المخصصة التي تعرض وظائف الخادم التي لا يتم تعيينها لعملية إدراج أو تحديث أو حذف أو قراءة. باستخدام واجهة برمجة تطبيقات مخصصة، يمكنك التحكم بشكل أكبر في المراسلة، بما في ذلك قراءة رؤوس رسائل HTTP وإعدادها وتحديد تنسيق نص الرسالة بخلاف JSON.

استدعاء واجهة برمجة تطبيقات مخصصة عن طريق استدعاء إحدى طرق InvokeApiAsync على العميل. على سبيل المثال، يرسل السطر التالي من التعليمات البرمجية طلب POST إلى إكمال واجهة برمجة التطبيقات All على الواجهة الخلفية:

var result = await client.InvokeApiAsync<MarkAllResult>("completeAll", System.Net.Http.HttpMethod.Post, null);

هذا النموذج هو استدعاء أسلوب مكتوب ويتطلب تعريف نوع الإرجاع MarkAllResult . يتم دعم كل من الأساليب المكتوبة وغير المكتوبة.

تقوم طريقة InvokeApiAsync() بإعداد "/api/" إلى واجهة برمجة التطبيقات التي ترغب في الاتصال بها ما لم تبدأ واجهة برمجة التطبيقات ب "/". على سبيل المثال:

  • InvokeApiAsync("completeAll",...) المكالمات / API / completeAll على الواجهة الخلفية
  • InvokeApiAsync("/.auth/me",...) المكالمات /.auth/me على الواجهة الخلفية

يمكنك استخدام InvokeApiAsync للاتصال بأي WebAPI، بما في ذلك واجهات WebAPI التي لم يتم تعريفها باستخدام Azure Mobile Apps. عند استخدام InvokeApiAsync()، يتم إرسال الرؤوس المناسبة، بما في ذلك رؤوس المصادقة، مع الطلب.

مصادقة المستخدمون

تدعم تطبيقات الجوال مصادقة مستخدمي التطبيق وتفويضهم باستخدام العديد من موفري الهوية الخارجيين: Facebook وGoogle وMicrosoft Account وTwitter وAzure Active Directory. يمكنك تعيين أذونات على الجداول لتقييد الوصول لعمليات معينة للمستخدمين المصادق عليهم فقط. يمكنك أيضا استخدام هوية المستخدمين المصادق عليهم لتنفيذ قواعد التخويل في البرامج النصية للخادم. لمزيد من المعلومات، راجع البرنامج التعليمي إضافة مصادقة إلى تطبيقك.

يتم دعم تدفقين للمصادقة: التدفق المدار من قبل العميل والتدفق المدار من قبل الخادم. يوفر التدفق المدار من قبل الخادم أبسط تجربة مصادقة ، حيث يعتمد على واجهة مصادقة الويب الخاصة بالموفر. يسمح التدفق المدار من قبل العميل بتكامل أعمق مع الإمكانات الخاصة بالجهاز لأنه يعتمد على مجموعات SDK الخاصة بالجهاز الخاص بالموفر.

ملاحظة

نوصي باستخدام تدفق يديره العميل في تطبيقات الإنتاج.

لإعداد المصادقة، يجب عليك تسجيل تطبيقك مع واحد أو أكثر من موفري الهوية. يقوم موفر الهوية بإنشاء معرف عميل وسر عميل لتطبيقك. ثم يتم تعيين هذه القيم في الواجهة الخلفية لتمكين مصادقة/تخويل خدمة تطبيقات Azure. لمزيد من المعلومات، اتبع الإرشادات التفصيلية الواردة في البرنامج التعليمي إضافة مصادقة إلى تطبيقك.

يتم تغطية الموضوعات التالية في هذا القسم:

المصادقة التي يديرها العميل

يمكن لتطبيقك الاتصال بشكل مستقل بموفر الهوية ثم توفير الرمز المميز الذي تم إرجاعه أثناء تسجيل الدخول باستخدام الواجهة الخلفية. يمكنك تدفق العميل هذا من توفير تجربة تسجيل دخول واحدة للمستخدمين أو استرداد بيانات مستخدم إضافية من موفر الهوية. يفضل مصادقة تدفق العميل على استخدام تدفق الخادم حيث توفر SDK الخاصة بموفر الهوية إحساسا أكثر أصلية بتجربة المستخدم وتسمح بتخصيص إضافي.

يتم توفير أمثلة لأنماط مصادقة تدفق العميل التالية:

مصادقة المستخدمين باستخدام مكتبة مصادقة Active Directory

يمكنك استخدام مكتبة مصادقة Active Directory (ADAL) لبدء مصادقة المستخدم من العميل باستخدام مصادقة Azure Active Directory.

  1. قم بتكوين الواجهة الخلفية لتطبيق الجوال لتسجيل الدخول AAD (دليل Azure النشط) باتباع البرنامج التعليمي كيفية تكوين خدمة التطبيقات لتسجيل الدخول إلى Active Directory. تأكد من إكمال الخطوة الاختيارية لتسجيل تطبيق عميل أصلي.

  2. في Visual Studio أو Xamarin Studio ، افتح مشروعك وأضف مرجعا إلى Microsoft.IdentityModel.Clients.ActiveDirectory حزمة NuGet. عند البحث، قم بتضمين إصدارات ما قبل الإصدار.

  3. أضف التعليمة البرمجية التالية إلى التطبيق الخاص بك ، وفقا للنظام الأساسي الذي تستخدمه. في كل منها ، قم بإجراء البدائل التالية:

    • استبدل INSERT-AUTHORITY-HERE باسم المستأجر الذي قدمت فيه طلبك. يجب أن يكون https://login.microsoftonline.com/contoso.onmicrosoft.comالتنسيق . يمكن نسخ هذه القيمة من علامة التبويب المجال في Azure Active Directory في مدخل Azure.

    • استبدل INSERT-RESOURCE-ID-HERE بمعرف العميل للواجهة الخلفية لتطبيق الجوال. يمكنك الحصول على معرف العميل من علامة التبويب خيارات متقدمة ضمن Azure Active Directory الإعدادات في البوابة الإلكترونية.

    • استبدل INSERT-CLIENT-ID-HERE بمعرف العميل الذي نسخته من تطبيق العميل الأصلي.

    • استبدل INSERT-REDIRECT-URI-HERE بنقطة النهاية /. auth/login/done الخاصة بموقعك، باستخدام مخطط HTTPS. يجب أن تكون هذه القيمة مشابهة ل https://contoso.azurewebsites.net/.auth/login/done.

      فيما يلي الرمز المطلوب لكل منصة:

      ⁩Windows:⁧

      private MobileServiceUser user;
      private async Task AuthenticateAsync()
      {
      
         string authority = "INSERT-AUTHORITY-HERE";
         string resourceId = "INSERT-RESOURCE-ID-HERE";
         string clientId = "INSERT-CLIENT-ID-HERE";
         string redirectUri = "INSERT-REDIRECT-URI-HERE";
         while (user == null)
         {
             string message;
             try
             {
                 AuthenticationContext ac = new AuthenticationContext(authority);
                 AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                     new Uri(redirectUri), new PlatformParameters(PromptBehavior.Auto, false) );
                 JObject payload = new JObject();
                 payload["access_token"] = ar.AccessToken;
                 user = await App.MobileService.LoginAsync(
                     MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
                 message = string.Format("You are now logged in - {0}", user.UserId);
             }
             catch (InvalidOperationException)
             {
                 message = "You must log in. Login Required";
             }
             var dialog = new MessageDialog(message);
             dialog.Commands.Add(new UICommand("OK"));
             await dialog.ShowAsync();
         }
      }
      

      Xamarin.iOS

      private MobileServiceUser user;
      private async Task AuthenticateAsync(UIViewController view)
      {
      
         string authority = "INSERT-AUTHORITY-HERE";
         string resourceId = "INSERT-RESOURCE-ID-HERE";
         string clientId = "INSERT-CLIENT-ID-HERE";
         string redirectUri = "INSERT-REDIRECT-URI-HERE";
         try
         {
             AuthenticationContext ac = new AuthenticationContext(authority);
             AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                 new Uri(redirectUri), new PlatformParameters(view));
             JObject payload = new JObject();
             payload["access_token"] = ar.AccessToken;
             user = await client.LoginAsync(
                 MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
         }
         catch (Exception ex)
         {
             Console.Error.WriteLine(@"ERROR - AUTHENTICATION FAILED {0}", ex.Message);
         }
      }
      

      Xamarin.Android

      private MobileServiceUser user;
      private async Task AuthenticateAsync()
      {
      
         string authority = "INSERT-AUTHORITY-HERE";
         string resourceId = "INSERT-RESOURCE-ID-HERE";
         string clientId = "INSERT-CLIENT-ID-HERE";
         string redirectUri = "INSERT-REDIRECT-URI-HERE";
         try
         {
             AuthenticationContext ac = new AuthenticationContext(authority);
             AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                 new Uri(redirectUri), new PlatformParameters(this));
             JObject payload = new JObject();
             payload["access_token"] = ar.AccessToken;
             user = await client.LoginAsync(
                 MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
         }
         catch (Exception ex)
         {
             AlertDialog.Builder builder = new AlertDialog.Builder(this);
             builder.SetMessage(ex.Message);
             builder.SetTitle("You must log in. Login Required");
             builder.Create().Show();
         }
      }
      protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
      {
      
         base.OnActivityResult(requestCode, resultCode, data);
         AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data);
      }
      

Sign-On واحد باستخدام رمز مميز من Facebook أو Google

يمكنك استخدام تدفق العميل كما هو موضح في هذا المقتطف لفيسبوك أو Google.

var token = new JObject();
// Replace access_token_value with actual value of your access token obtained
// using the Facebook or Google SDK.
token.Add("access_token", "access_token_value");

private MobileServiceUser user;
private async Task AuthenticateAsync()
{
    while (user == null)
    {
        string message;
        try
        {
            // Change MobileServiceAuthenticationProvider.Facebook
            // to MobileServiceAuthenticationProvider.Google if using Google auth.
            user = await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);
            message = string.Format("You are now logged in - {0}", user.UserId);
        }
        catch (InvalidOperationException)
        {
            message = "You must log in. Login Required";
        }

        var dialog = new MessageDialog(message);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
}

المصادقة المدارة من قبل الخادم

بمجرد تسجيل موفر الهوية الخاص بك، اتصل بطريقة تسجيل الدخول Async على [MobileServiceClient] مع قيمة MobileServiceAuthenticationProvider الخاصة بموفر الخدمة. على سبيل المثال، تبدأ التعليمة البرمجية التالية تسجيل الدخول إلى تدفق الخادم باستخدام Facebook.

private MobileServiceUser user;
private async System.Threading.Tasks.Task Authenticate()
{
    while (user == null)
    {
        string message;
        try
        {
            user = await client
                .LoginAsync(MobileServiceAuthenticationProvider.Facebook);
            message =
                string.Format("You are now logged in - {0}", user.UserId);
        }
        catch (InvalidOperationException)
        {
            message = "You must log in. Login Required";
        }

        var dialog = new MessageDialog(message);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
}

إذا كنت تستخدم موفر هوية آخر غير فيسبوك، فقم بتغيير قيمة MobileServiceAuthenticationProvider إلى القيمة الخاصة بموفر الخدمة.

في تدفق الخادم، تدير Azure App Service تدفق مصادقة OAuth عن طريق عرض صفحة تسجيل الدخول الخاصة بالموفر المحدد. بمجرد عودة موفر الهوية، تقوم Azure App Service بإنشاء رمز مميز لمصادقة خدمة التطبيق. ترجع طريقة LoginAsyncMobileServiceUser، التي توفر كل من UserId للمستخدم المصادق عليه وMobileServiceAuthenticationToken، كرمز ويب JSON (JWT). يمكن تخزين هذا الرمز المميز مؤقتا وإعادة استخدامه حتى تنتهي صلاحيته. لمزيد من المعلومات، راجع التخزين المؤقت للرمز المميز للمصادقة.

عند استخدام Xamarin (إما Android أو iOS) ، يتم استخدام Xamarin.Essentials WebAuthenticator. يجب تمرير السياق الافتراضي (Android) أو UIViewController (iOS) إلى LoginAsync الطريقة. بالإضافة إلى ذلك ، يجب عليك التعامل مع الإرجاع من مصادق الويب. في Android ، يتم التعامل مع هذا ضمن MainActivity.cs:

public override void OnResume()
{
    base.OnResume();
    Xamarin.Essentials.Platform.OnResume();
}

على iOS ، يتم التعامل مع هذا داخل AppDelegate .cs':

public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
    if (client.ResumeWithURL(app, url, options))
        return true;
    return base.OpenUrl(app, url, options);
}

التخزين المؤقت لرمز المصادقة

في بعض الحالات، يمكن تجنب الاتصال بطريقة تسجيل الدخول بعد المصادقة الناجحة الأولى عن طريق تخزين الرمز المميز للمصادقة من الموفر. يمكن لتطبيقات Microsoft Store وUWP استخدام PasswordVault لتخزين الرمز المميز للمصادقة الحالي مؤقتا بعد تسجيل الدخول بنجاح، على النحو التالي:

await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook);

PasswordVault vault = new PasswordVault();
vault.Add(new PasswordCredential("Facebook", client.currentUser.UserId,
    client.currentUser.MobileServiceAuthenticationToken));

يتم تخزين قيمة UserId كاسم المستخدم لبيانات الاعتماد ويتم تخزين الرمز المميز ككلمة مرور. في عمليات بدء التشغيل اللاحقة، يمكنك التحقق من PasswordVault بحثا عن بيانات الاعتماد المخزنة مؤقتا. يستخدم المثال التالي بيانات الاعتماد المخزنة مؤقتا عند العثور عليها، وبخلاف ذلك يحاول المصادقة مرة أخرى باستخدام الواجهة الخلفية:

// Try to retrieve stored credentials.
var creds = vault.FindAllByResource("Facebook").FirstOrDefault();
if (creds != null)
{
    // Create the current user from the stored credentials.
    client.currentUser = new MobileServiceUser(creds.UserName);
    client.currentUser.MobileServiceAuthenticationToken =
        vault.Retrieve("Facebook", creds.UserName).Password;
}
else
{
    // Regular login flow and cache the token as shown above.
}

عند تسجيل خروج مستخدم، يجب عليك أيضا إزالة بيانات الاعتماد المخزنة، كما يلي:

client.Logout();
vault.Remove(vault.Retrieve("Facebook", client.currentUser.UserId));

تستخدم تطبيقات Xamarin واجهات برمجة تطبيقات Xamarin.Auth لتخزين بيانات الاعتماد بشكل آمن في كائن حساب . للحصول على مثال لاستخدام واجهات برمجة التطبيقات هذه، راجع ملف التعليمات البرمجية AuthStore.cs في نموذج مشاركة صور ContosoMoments.

عند استخدام المصادقة التي يديرها العميل، يمكنك أيضا تخزين رمز الوصول المميز الذي تم الحصول عليه من موفر الخدمة الخاص بك مثل Facebook أو Twitter. يمكن توفير هذا الرمز المميز لطلب رمز مصادقة جديد من الواجهة الخلفية ، على النحو التالي:

var token = new JObject();
// Replace <your_access_token_value> with actual value of your access token
token.Add("access_token", "<your_access_token_value>");

// Authenticate using the access token.
await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);

دفع الإخطارات

تغطي الموضوعات التالية الإعلامات الفورية:

كيفية: التسجيل للحصول على الإشعارات الفورية

يمكنك عميل تطبيقات الجوال من التسجيل للحصول على إعلامات الدفع باستخدام مراكز إعلام Azure. عند التسجيل، يمكنك الحصول على مقبض تحصل عليه من خدمة الإشعارات المباشرة (PNS) الخاصة بالنظام الأساسي. ثم يمكنك توفير هذه القيمة جنبا إلى جنب مع أي علامات عند إنشاء التسجيل. تسجل التعليمة البرمجية التالية تطبيق Windows الخاص بك للحصول على إشعارات فورية مع خدمة إشعارات Windows (WNS):

private async void InitNotificationsAsync()
{
    // Request a push notification channel.
    var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

    // Register for notifications using the new channel.
    await MobileService.GetPush().RegisterNativeAsync(channel.Uri, null);
}

إذا كنت تدفع إلى WNS ، فيجب عليك الحصول على حزمة SID Microsoft Store. لمزيد من المعلومات حول تطبيقات Windows، بما في ذلك كيفية التسجيل في تسجيلات القوالب، راجع إضافة إشعارات فورية إلى تطبيقك.

طلب العلامات من العميل غير مدعوم. يتم إسقاط طلبات العلامات بصمت من التسجيل. إذا كنت ترغب في تسجيل جهازك باستخدام العلامات، فقم بإنشاء واجهة برمجة تطبيقات مخصصة تستخدم واجهة برمجة تطبيقات مراكز الإشعارات لإجراء التسجيل نيابة عنك. اتصل بواجهة برمجة التطبيقات المخصصة بدلا من RegisterNativeAsync() الطريقة.

كيفية: الحصول على حزمة Microsoft Store SID

هناك حاجة إلى حزمة SID لتمكين الإشعارات المباشرة في تطبيقات Microsoft Store. للحصول على حزمة SID ، قم بتسجيل طلبك لدى Microsoft Store.

للحصول على هذه القيمة:

  1. في Visual Studio مستكشف الحلول، انقر بزر الماوس الأيمن فوق مشروع تطبيق Microsoft Store، وانقر فوق تطبيق StoreAssociate>مع المتجر....
  2. في المعالج، انقر فوق التالي، وسجل الدخول باستخدام حساب Microsoft الخاص بك، واكتب اسما لتطبيقك في حجز اسم تطبيق جديد، ثم انقر على حجز.
  3. بعد إنشاء تسجيل التطبيق بنجاح، حدد اسم التطبيق، وانقر فوق التالي، ثم انقر فوق إقران.
  4. قم بتسجيل الدخول إلى Windows مركز التطوير باستخدام حساب Microsoft الخاص بك. ضمن تطبيقاتي، انقر فوق تسجيل التطبيق الذي أنشأته.
  5. انقر فوق إدارة>التطبيقاتهوية التطبيق، ثم مرر لأسفل للعثور على حزمة SID الخاص بك.

تتعامل العديد من استخدامات الحزمة SID معها على أنها عنوان URI ، وفي هذه الحالة تحتاج إلى استخدام ms-app:// كمخطط. دون إصدار الحزمة SID التي تم تشكيلها عن طريق تسلسل هذه القيمة كبادئة.

تتطلب تطبيقات Xamarin بعض التعليمات البرمجية الإضافية لتتمكن من تسجيل تطبيق يعمل على نظامي التشغيل iOS أو Android. لمزيد من المعلومات، راجع الموضوع الخاص بالنظام الأساسي الخاص بك:

كيفية: تسجيل قوالب الدفع لإرسال إشعارات عبر الأنظمة الأساسية

لتسجيل القوالب RegisterAsync() ، استخدم الطريقة مع القوالب، كما يلي:

JObject templates = myTemplates();
MobileService.GetPush().RegisterAsync(channel.Uri, templates);

يجب أن تكون القوالب الخاصة بك أنواعا JObject ويمكن أن تحتوي على قوالب متعددة بتنسيق JSON التالي:

public JObject myTemplates()
{
    // single template for Windows Notification Service toast
    var template = "<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$(message)</text></binding></visual></toast>";

    var templates = new JObject
    {
        ["generic-message"] = new JObject
        {
            ["body"] = template,
            ["headers"] = new JObject
            {
                ["X-WNS-Type"] = "wns/toast"
            },
            ["tags"] = new JArray()
        },
        ["more-templates"] = new JObject {...}
    };
    return templates;
}

الطريقة RegisterAsync() يقبل أيضا البلاط الثانوي:

MobileService.GetPush().RegisterAsync(string channelUri, JObject templates, JObject secondaryTiles);

يتم تجريد جميع العلامات أثناء التسجيل للأمان. لإضافة علامات إلى عمليات التثبيت أو القوالب داخل عمليات التثبيت، راجع [العمل باستخدام حزمة SDK لخادم الواجهة الخلفية .NET لتطبيقات Azure للأجهزة المحمولة].

لإرسال إشعارات باستخدام هذه القوالب المسجلة، راجع واجهات برمجة تطبيقات مراكز الإشعارات.

مواضيع متنوعة

كيفية: التعامل مع الأخطاء

عند حدوث خطأ في الواجهة الخلفية، تقوم حزمة SDK الخاصة بالعميل برفع ملف MobileServiceInvalidOperationException. يوضح المثال التالي كيفية التعامل مع استثناء يتم إرجاعه بواسطة الواجهة الخلفية:

private async void InsertTodoItem(TodoItem todoItem)
{
    // This code inserts a new TodoItem into the database. When the operation completes
    // and App Service has assigned an Id, the item is added to the CollectionView
    try
    {
        await todoTable.InsertAsync(todoItem);
        items.Add(todoItem);
    }
    catch (MobileServiceInvalidOperationException e)
    {
        // Handle error
    }
}

يمكن العثور على مثال آخر للتعامل مع حالات الخطأ في نموذج ملفات تطبيقات الجوال. يوفر مثال LoggingHandler معالج مفوض تسجيل لتسجيل الطلبات التي يتم إجراؤها إلى الواجهة الخلفية.

كيفية القيام بما يلي: تخصيص رؤوس الطلبات

لدعم سيناريو تطبيقك المحدد، قد تحتاج إلى تخصيص الاتصال باستخدام الواجهة الخلفية لتطبيق الجوال. على سبيل المثال، قد ترغب في إضافة رأس مخصص إلى كل طلب صادر أو حتى تغيير رموز حالة الردود. يمكنك استخدام معالج تفويض مخصص، كما في المثال التالي:

public async Task CallClientWithHandler()
{
    MobileServiceClient client = new MobileServiceClient("AppUrl", new MyHandler());
    IMobileServiceTable<TodoItem> todoTable = client.GetTable<TodoItem>();
    var newItem = new TodoItem { Text = "Hello world", Complete = false };
    await todoTable.InsertAsync(newItem);
}

public class MyHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage>
        SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // Change the request-side here based on the HttpRequestMessage
        request.Headers.Add("x-my-header", "my value");

        // Do the request
        var response = await base.SendAsync(request, cancellationToken);

        // Change the response-side here based on the HttpResponseMessage

        // Return the modified response
        return response;
    }
}