פיתוח אפליקציית Windows Phone לשליחת SMS [מדריך]

אם אתם מפתחים ויש לכם Windows Phone או במידה ואתם מעוניינים לפתח אפליקציות עבור Windows Phone, אז הנה מדריך קצר הכולל גם הצצה לפיתוח אפליקציית Silverlight

תמונה: יח"צ

תומר שמם הינו ארכיטקט תוכנה, יועץ, מרצה ומומחה UI בחברת CodeValue, בעל ניסיון רב בפיתוח ובליווי פרוייקטי תוכנה במגוון רחב של תחומים. תוכלו למצוא מאמרים נוספים שלו גם בבלוג האישי שלו.

למי שכבר יצא להחליף מספר טלפון בעבר, בטח יודע להעריך כמה עבודה כרוכה בנושא שליחת SMS-ים על עדכון מספר הטלפון. בגדול, לא משנה איזה טלפון יש לכם, צריך לפתוח את תוכנת ההודעות הבנויה, לכתוב הודעה על שינוי מספר הטלפון ואז להוסיף נמענים מרשימה. הבעיה מתחילה כשיש לכם יותר מ-100 נמענים, חלקם ניידים, וחלקם לא וצריך לבצע מספר פעולות על כל נמען כדי להחליט אם להוסיפו לרשימה, או סינון נמענים שאינם רלוונטיים, ואז הוספת נמענים ושליחת הודעה.

למה לעבוד קשה?

אם אתם מפתחים ויש לכם Windows Phone או מעונינים לייצר אפליקציות עבור Windows Phone, אז אחרי שתקראו מדריך זה תגלו שהרבה יותר קל לפתח אפליקצית Silverlight פשוטה לטלפון שמבצעת משימה זו, וגם תוכלו להעלות אותה למרקט פלייס ולעשות קצת כסף.

התקנת סביבת פיתוח

לפני שמתחילים, צריך להכין סביבת פיתוח, ואם אתם מעונינים שהאפליקציה גם תרוץ על הטלפון שלכם ולא רק על האמולטור שמגיע עם סביבת הפיתוח, אז צריך לפתוח את הטלפון לפיתוח. כדי להתקין סביבת פיתוח ל- Windows Phone, כל מה שצריך זה להוריד מאתר APP HUB, אתר הפיתוח עבור Windows Phone ועבור XBOX 360 של מיקרוסופט, את כלי העבודה בחינם. מכלול כלי פיתוח זה נקרא Windows Phone SDK 7.1, וניתן להוריד אותו מהכתובת הבאה.

כלי הפיתוח כוללים בתוכם:

Microsoft Visual Studio 2010 Express for Windows Phone: סביבת הפיתוח המפורסמת של מיקרוסופט.

Windows Phone Emulator: אמולטור תוכנה שמדמה מכשיר אמיתי, בעזרתו תוכלו להריץ ולדבג את האפליקציות שתכתבו, גם אם אין ברשותכם מכשיר אמיתי.

Windows Phone SDK 7.1 Assemblies: קבצי ספריה שכוללים בתוכם כל מה שצריך לפיתוח תוכנה עבור Windows Phone בעזרת Silverlight ו/או XNA.

Microsoft Expression Blend SDK for Windows Phone 7: תוכנה שמאפשרת לבנות ממשק משתמש עשיר ולייצר חווית משתמש ייחודית עבור האפליקציות שלכם, ולעצב אותם בצורה קלה, נוחה ויעילה, בעזרת עורך גרפי ושפה שנקראת XAML.

פתיחת הטלפון לפיתוח

כדי להתקין תוכנה שיצרתם על מכשירכם, יש צורך לשחרר נעילה לפיתוח. הנה שלוש דרכים חוקיות לעשות זאת:

1. באופן רשמי דרך מיקרוסופט: פתיחת חשבון ורישום באתר APP HUB שהוזכר קודם לכן.

2. לא רשמי דרך YallaApps – פתיחת חשבון ורישום באתר YallaApps.

3. לא רשמי – פתיחת מכשירכם בעזרת ChevronWP7 Labs במחיר סימלי של 9 דולרים.

ההבדל בין שלושת הדרכים:

הדרך הראשונה יקרה יותר, וקצובה בזמן של שנה שלאחר מכן יש צורך בתשלום נוסף וכן הלאה, אך מעניקה אפשרות להעלות אפליקציות למרקט פלייס ולעשות מהם כסף. כמו כן יש תמיכה מלאה ממיקרוסופט, שכן זו הדרך הרישמית והמומלצת לעשות זאת.

הדרך השנייה, זולה במקצת. כאשר YallaApps משמשת כ- Publisher לאפליקציות שלכם, ואתם מקבלים אחוזים על כל מכירה. יתרון אם אין לכם אפשרות להרשם ב- APP HUB מסיבה כזו או אחרת.

הדרך השלישית זולה יותר, ואינה מוגבלת בזמן, אך אינה מעניקה אפשרות להעלות את האפליקציות שלכם למרקט פלייס ולא ניתנת תמיכה ממיקרוסופט בתקלות שכרוכות בשירות זה. דרך זו מומלצת עבור אירגונים שמעונינים לפתח אפליקציות פנים אירגוניות, ואינם מעונינים לפרסם את האפליקציות שלהם במרקט פלייס.

דרישות תוכנה

כמו בכל שלב בפיתוח תוכנה, יש להגדיר היטב מהן הדרישות מהתוכנה שאתם עומדים לכתוב. לצורך הפשטות במדריך זה נקצר את התהליך ונגדיר מספר מינימלי של דרישות:

1. הצגת רשימת נמענים בעלי מספר טלפון נייד בלבד.
2. בחירה מהירה של נמענים רלוונטיים מתוך הרשימה.
3. עריכת הודעת SMS לפני שליחה.
4. שליחת הודעת SMS לנמענים שסומנו בלבד.
5. סינון נמענים מהרשימה לאחר שליחה.

עכשיו כשאנחנו פחות או יותר מבינים מה הצורך, נתקדם לשלב הבא: שלב יצירת ממשק המשתמש.

יצירת ממשק משתמש

ראשית, יש ליצור פרייקט חדש. כדי לעשות זאת יש לפתוח את Visual Studio שהותקן כחלק מכלי הפיתוח ואז לבחור יצירת פרוייקט חדש מתפריט ה-File.

לאחר מכן יש לבחור Silverlight for Windows Phone ואז Windows Phone Application שיוצרת פרוייקט Windows Phone חדש ריק, עם דף אחד. לצורך אחידות, יש לקרוא לפרוייקט SendSmsApp.

יצרנו פרוייקט בגדול מסוג Silverlight. טכנולוגיה לפיתוח אפליקציות עם יכולות ממשק משתמש מרשימות במיוחד ואפשרות כתיבה בשפות C# ו- Visual Basic. במדריך זה נתמקד בשפת C# שהיא שפה נפוצה יותר בקרב מתכנתי Silverlight ודוט-נט. כעת כשיש לנו פרוייקט חדש, בואו נביט בעץ הפתרון (Solution Explorer) שנמצא בצד ימין.

מבנה הפתרון מורכב במקרה שלנו מפרוייקט אחד: SendSMSApp. בתוך הפרוייקט קיימים מספר פריטים. שני פריטים חשובים הם App, MainPage. הפריט הראשון, App, מייצג את האפליקציה ומנהל את אורך החיים שלה. הפריט השני, MainPage, מייצג את הדף הראשי שיפתח כשהאפליקציה תתחיל לרוץ. במדריך זה נתמקד בדף הראשי ונוסיף רכיבי ממשק משתמש לתוכו.

כעת כשיש לנו פרוייקט חדש, בואו נפתח את הדף הראשון ונזרוק קצת תוכן.

בעץ הפרוייקט מצד ימין יש לפתוח את MainPage.xaml. זה יפתח את המעצב הגרפי ובנוסף עורך XAML, שפתXML פשוטה שמתארת כל דבר ויזואלי שרואים בממשק המשתמש, סוג הרכיב הויזואלי, מיקומו והתנהגות ויזואלית.

הערה: לרוב ניתן לכתוב ממשק משתמש מלא בעזרת העורך בלבד, מבלי לכתוב XAML. למתקדמים יש יכולות נוספות ושליטה מלאה ברכיב הויזואלי בעזרת XAML. בנוסף Expression Blend מאפשר לבצע דברים מורכבים יותר בהקשר להתנהגות ויזואלית כמו יצירת אנימציות. עבודה עם Blend מחוץ למסגרת מדריך זה.

כעת בדף שנפתח נשנה את הכותרת ושם האפלקציה שתוצג למשתמש דרך העורך הגרפי. יש לבחור את הרכיב שמציג את Application Title ולשנות את ה- Text ל- SMS ALL. את זה נעשה בעזרת חלון Properties שנמצא מתחת לעץ הפרוייקט בצד ימין. נחפש את התכונה (Property) שנקראת Text ונשנה אותה. את אותה פעולה נבצע פעם נוספת עבור כותרת האפליקציה, והפעם נכתוב: Contacts.

אם נביט ב- XAML של רכיבים אלו, אז הוא נראה כך:

הערה: הרכיב TextBlock מתאר טקטס פשוט שאינו ניתן לעריכה. כדי לערוך טקסט יש להשתמש ברכיב שנקרא TextBox, או RichTextBox. הרכיב StackPanel מסדר את הרכיבים הבנים אחד מתחת לשני.

כעת נוסיף רכיב מסוג ListBox שיציג את רשימת הנמענים, ורכיב TextBox שיאפשר לערוך את הודעת ה- SMS. כדי להוסיף רכיב חדש, יש לבחור את סוג הרכיב מחלונית Toolbox שנמצאת בצד שמאל של הסביבה. לאחר בחירה, יש לגרור את הרכיב למיקום הרצוי בעורך הגרפי או לחילופין, ללחוץ על הרכיב פעמיים.

כדי לאפשר למשתמש להזין יותר משורה אחת של טקטס ברכיב ה- TextBox, יש לבחור אותו ולשנות את התכונה שנקראת AcceptsReturn ל- True.

אחרי שהוספתם את הרכיבים, קבעתם את גודלם ומיקומם, ה-XAML יראה כך:

הערה: הרכיב Grid מאפשר לסדר את הרכיבים בתוכו בתצורת טבלה. אחת מהאפשרויות זה סידור פרופורציונאלי יחסי, ולא גודל קבוע. במקרה שלנו יחס 70% לשורה ראשונה, 30% לשורה שנייה. בנוסף כל רכיב אומר איפה הוא רוצה להתמקם: Grid.Row.

שלב נוסף בעריכת ממשק המשתמש הוא יצירת Application Bar שיציג פעולות שכיחות בתחתית הדף ויאפשר לבצען. בכל דף (Page) חדש שמוסיפים לפרוייקט מופיע Application Bar אופציונאלי בתחתית. שימו לב שהוא מסומן כהערת XML ולכן יש לבטל אותה. כדי לעשות זאת נוריד מה- XAML את התגים שהופכים אותו להערה.

כמו שניתן לראות, ב-Application Bar למעלה בוצעו שינויים נוספים. הכנסת MenuItems להערה, שכן אין צורך בהם באפליקציה זו, ומחיקת ApplicationBarIconButton מיותרים ועדכון הרלוונטיים.

הערה: הרכיב ApplicationBarIconButton מוצג ככפתור עגול על גבי ה-ApplicationBar בתחתית הדף. לחיצה עליו מפעילה מטודה (פונקציה של מחלקה) שנוסיף בהמשך. ניתן להוסיף לכל כפתור תמונה וכיתוב (IconUri, Text).

כעת נוסיף שתי קבצי תמונה לפרוייקט תחת תיקייה Images שניצור. לקובץ הראשון נקרא appbar_filter.png, ולשני appbar_send.png.
ראשית ניצור תיקייה בשם Images בצורה הבאה (לחיצה כפתור ימני על שם הפרוייקט):

לאחר מכן נוסיף את שתי הצלמייות לתיקייה שיצרנו בצורה הבאה (לחיצה כפתור ימני על התיקייה):

הערה: ניתן למצוא רשימת צלמיות בסיסית בתיקייה %ProgramFiles%\Microsoft SDKs\Windows Phone\v7.1\Icons\dark שנוצרה כחלק מהתקנת ה-SDK.

אחרי שהוספנו שתי צלמיות הפרוייקט אמור להראות כך:

הערה: גודל צלמית ב-ApplicationBar צריך להיות 48×48. ה-Build Action חייב להיות Content ו Copy to Output Directory צריך להיות Copy if newer. תכונות אלו נראה בחלונית Properties אם נבחר את אחת הצלמיות.

כעת יש לעדכן כל אחד מהכפתורים שהוספנו קודם לכן ל- Application Bar.

עד כה העמוד (MainPage.xaml) אמור להכיל את הדברים הבאים:

הרצה מהירה של האפליקציה שבנינו עד כה ע”י לחיצה על כפתור F5 בויזואל סטודיו, תפעיל את האמולטור, והוא יראה כך:

יצירת לוגיקה אפליקטיבית

עד כה יצרנו ממשק משתמש בסיסי. בהמשך נוסיף חלקים נוספים לממשק, אבל קודם לכן ניצור את הלוגיקה האפליקטיבית שתופעל בעזרת ממשק המשתמש.

לשם כך נתמקד בקבצים עם סייומת “.cs”, או במילים אחרות קבצים שיכילו קוד בשפת C#, שפת התכנות שנבחרה למדריך זה (ישנה אפשרות לכתוב בשפת Visual Basic).

מתחת לקובץ MainPage.xaml ישנו קובץ שנקרא MainPage.xaml.cs. בקובץ זה נוסיף את הלוגיקה שעומדת מאחורי הדף הראשי.

הערה: באופן כללי, מומלץ לבצע הפרדה בין לוגיקת ממשק המשתמש לבין לוגיקת האפליקציה. היתרונות: קוד ברור יותר שיותר קל לתחזק עם הזמן, יותר קל לבדוק ולעצב. אחד מה- Design Patterns הנפוצים לשם כך נקרא MVVM. ניתן להעזר בערכת פיתוח חינמית בשם MVVM Light שמספקת כלים בסיסיים לפיתוח אפליקציות בסגנון זה. כמובן שיש עוד ערכות ופתרונות נוספים. למען הפשטות, מדריך זה אינו עוסק ב- MVVM.

ראשית ניצור שתי מחלקות חדשות בשם ValidContact, ValidContacts. הראשונה תחזיק את פרטי הקשר של רשומה תקינה שמכילה מספר טלפון נייד, והשנייה תחזיק רשומות תקינות אותן נציג בממשק המשתמש.

המחלקה ValidContact מכילה פרטים בסיסיים שאותם נציג למשתמש, כגון שם הנמען, מס’ טלפון, ותכונה נוספת שנעזר בה כדי לזהות מי הרשומה שנבחרה ברשימה.

המחלקה ValidContacts מכילה רשימה של ValidContact, ומחצינה אותה כתכונה (Property) בשם Contacts. ובנוסף תכונה שנקראת SmsMessage שנעזר בה להצגת ושליחת תוכן ההודעה.

כעת נוסיף פונקציה בונה (Constructor) שבעזרתה נאתחל את הרשימה.

בהמשך נעזר במחלקה Contact שמגיעה עם ה- SDK. מחלקה זו מייצגת רשומה בטלפון. ממנה נחלץ נתונים רלוונטיים, נבצע סינון, ונאתחל את המחלקות שלנו. כדי להכין את הקרקע, ניצור פונקציה בונה נוספת שהפעם מקבלת רשימת Contact ומבצעת סינון רשומות לא רלוונטיות שאינן מכילות מס’ טלפון נייד. לשם כך נשתמש באחת מהיכולות של שפת C# שנקראת LINQ to Objects, שמאפשרת לתשאל רשימות בסגנון SQL.

מה שקורה כאן בגדול, זה ביצוע שאילתה בסגנון select-from-where של SQL, אל מול הרשימה contacts שנשלחה כפרמטר לפונקציה הבונה, עבור כל רשומה בחירת מספר הטלפון הראשון מסוג טלפון נייד, contact.PhoneNumbers.FirstOrDefault(p => p.Kind == PhoneNumberKind.Mobile), ואז יצירת אובייקט שלנו מסוג ValidContact עם הערכים הרלוונטיים בלבד. לבסוף אתחול משתנה המחלקה שיחזיק את הרשימה עם הטלפונים הרלוונטיים.

כעת, ניצור מופע את המחלקה ValidContacts מתוך הדף הראשי, ונחצין אותו לממשק המשתמש לטובת קשירת נתונים (Data Binding) והצגתם.

לשם כך, נפתח את הקובץ MainPage.xaml.cs ונוסיף את התכונה הבאה:

התכונה DataContext שייכת למחלקה MainPage (במקור נורשת מ- FrameworkElement). כדי לקשור את הנתונים מאוחר יותר עם כל אחד מהפקדים שהוספנו בממשק המשתמש, יש צורך שהתכונה DataContext תהיה מאותחלת עם אובייקט שמכיל את הנתונים לתצוגה, ValidContacts.

כעת יש לבצע חיפוש בטלפון אחר רשומות. את זה נעשה בעזרת המחלקה Contacts שמגיעה עם ה- SDK בצורה הבאה:

מה שעשינו פה בעצם זה יצירת בקשה אסינכרונית מול Contacts לביצוע חיפוש, ע”י קריאה למטודה SearchAsync. שורה אחת לפני, נרשמנו לאירוע SearchCompleted שיופעל כשהבקשה תסתיים. בתוך המטודה conacts_SearchCompleted מחלצים את הרשומות שנמצאו ומאתחלים את התכונה Model שיצרנו קודם לכן עם אובייקט ValidContacts חדש.

נרחיב את המחלקה עם שתי מטודות נוספות. אחת מבצעת סינון לרשומות בחורות והשניה לרשומות שאינן בחורות. נשתמש במטודות אלה אח”כ.

המטודה הראשונה, RemoveUnselected, נעזרת שוב ב- LINQ, הפעם לבחור אובייקטים מסומנים, IsSelected, ואיפוס המשתנה IsSelected לאחר מכן. המטודה השנייה, RemoveSelected, נעזרת שוב ב- LINQ, הפעם לבחור אובייקטים שאינם מסומנים, IsSelected. שתי המטודות מאתחלות שוב את Model עם אובייקט ValidContacts חדש.

כעת נוסיף קטע קוד לשליחת SMS. את זה נעשה בעזרת המחלקה SmsComposeTask. מחלקה זו שמגיעה כחלק מה- SDK מאפשרת לשלוח SMS בצורה מאובטחת.

הערה: לא ניתן לבצע פעולות על הטלפון שעלולות לפגוע במשתמש מבלי שהמשתמש יהיה מודע לכך ויאשר אותן. פעולות מסוג זה מבצעים בעזרת רשימת מחלקות ידועה מראש בשם Launchers and Choosers, כאשר SmsComposeTask היא אחת מהן.

כדי לשלוח SMS, יש להוסיף את קטע הקוד הבא:

מה שעשינו פה זה בחירת רשומות בחורות, בניית מחרוזת אחת ארוכה שמשרשרת את רשימת מספרי הטלפון של הנמענים עם “;” בין רשומה לרשומה, יצירת SmsComposeTask ואיתחולו ברשימה זו, ובתכולת ההודעה שיש לשלוח. לאחר מכן הפעלת Show כדי להפעיל את ה- Task.

כעת נקשור את ממשק המשתמש לנתונים אלו. נעשה זאת בעזרת תכונה של Silverlight שנקראת Data Binding.

נפתח את MainPage.xaml, נבחר את ה- ListBox שהוספנו קודם לכן ונוסיף לו את התכונות הבאות:

התכונה העיקרית, ItemsSource=”{Binding Contacts}” קושרת את ה- ListBox לתכונה Contacts ששייכת ל- ValidContacts (להזכירכם, יצרנו אובייקט כזה ושמנו אותו ב- DataContext לשם כך). כעת כשיווצר האובייקט ListBox הוא אוטומטית יאותחל עם רשימת הנמענים הרלוונטית.

אם נריץ את מה שיש לנו עד כה, נוכל לראות את רשימת הנמענים הראשונית שקיימת על האמולטור (לחיצה על F5):

ניתן לראות כעת שה- ListBox מאותחל עם רשימת הנמענים הראשונית. מאחר שאובייקט ValidContact אינו אובייקט ויזואלי, אלא אובייקט נתונים פשוט, אנו רואים מחרוזת סתמית “SmsAll.ValidContact” בכל אחת מהרשומות ברשימה.

כעת ניצור אובייקט ויזואלי עבור כל אחת מהרשומות. נעשה זאת בעזרת תכונה שנראת Data Template בצורה הבאה:

הערה: Data Template זאת תכונה ב- Silverlight שמאפשרת להציג אובייקט לא ויזואלי כאוביקט ויזואלי, באופן גורף כפי שנעשה לכל אובייקט ברשימה. במקרה שלנו הצגת ValidContact.

שימו לב, כחלק מיצירת DataTemplate עבור אובייקט הנתונים שלנו ValidContact, השתמשנו שוב בביטוי Binding כדי לקשור כל אחד מהפקדים בתוך תבנית ה- DataTemplate לתכונות שונות באובייקט הנתונים.

אם נריץ את האפליקציה שוב, היא תראה כך: