1. לפני שמתחילים
ה-Codelab הזה הוא פעילות מס' 2 בנתיב 'תחילת העבודה עם סיווג טקסט בנייד'.
ב-Codelab הזה תפתחו אפליקציה פשוטה להעברת הודעות. בהמשך התהליך, יהיה עליך לעדכן את האפליקציה הזו עם מודל למידת מכונה שיסנן ספאם לא רצוי מההודעות באפליקציה.
דרישות מוקדמות
- ידע בסיסי בפיתוח Android ב-Kotlin ופיתוח (אופציונלי) ב-iOS באמצעות Swift
מה תפַתחו
- אפליקציית הודעות פשוטה
למה תזדקק?
- ב-Android, כדי להתחיל, צריך Android Studio. לפני שממשיכים, חשוב לוודא שהאפליקציה מותקנת ועדכנית במלואה.
- ב-iOS, יש צורך ב-Xcode. אפשר למצוא את האפליקציה הזו ב-App Store. (אם אתם רוצים לכתוב רק את האפליקציה ל-iOS, דלגו ישירות לשלב 5.
קבל את הקוד
אם אתם לא רוצים לעקוב אחרי שלב אחרי שלב ואתם רואים רק את הקוד הסופי של הנתיב הזה,
git clone https://github.com/googlecodelabs/odml-pathways
כאן מוצאים את הספרייה TextClassificationOnMobile, ובתוכם ניתן לראות את ספריות המשנה של Android ו-iOS. הספריות האלה יכילו ספריות משנה מסוג TextClassificationStep1, שמכילות את האפליקציה ב-Android וב-iOS, בהתאמה.
2. יצירת פרויקט חדש ב-Android Studio
- מפעילים את Android Studio.
- בוחרים באפשרות Create New Project (יצירת פרויקט חדש). עכשיו תופיע תיבת דו-שיח שבה תתבקשו לבחור תבנית לפרויקט.
- בוחרים באפשרות ריקון הפעילות ולוחצים על הבא. בשלב הבא תתבקשו להגדיר את הפרויקט. בוחרים מה שרוצים, אבל חשוב לוודא שהשפה היא Kotlin ושה-SDK המינימלי הוא API 23.
- לוחצים על סיום. לאחר מכן, מערכת Android Studio תיפתח עם הפרויקט שלך. יכול להיות שיחלפו כמה דקות עד שיתבצע סנכרון הדרגתי כדי לוודא שהכול בסדר, במיוחד אם זו הפעם הראשונה שאתם משתמשים ב-Android Studio.
3. יצירת ממשק המשתמש
ממשק המשתמש של אפליקציה ל-Android נוצר באמצעות קובץ XML שנקרא קובץ פריסה.
- פתח את הקובץ. לוחצים על אפליקציה > res > layout > activity_main.xml באמצעות הסייר ב-Android Studio.
בפינה השמאלית העליונה של המסך אתם אמורים לראות תפריט עם כרטיסיות כמו 'קוד', 'פיצול' ו'עיצוב', כמו בדוגמה הבאה:
יש לוודא שהאפשרות Code (קוד) מסומנת לפני מעבר לשלב הבא.
- מחליפים את הקוד ב-XML הבא:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter a string:"></TextView>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/txtInput"></EditText>
</LinearLayout>
<TextView
android:id="@+id/txtOutput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Output Goes here"
android:textSize="36sp"></TextView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnSendText"
android:text="Send"></Button>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
מתקבל ממשק משתמש בסיסי שמכיל אזור להזנת קלט עם TextView, ומתבקש הזנת מחרוזת ו-EditText בשם txtInput שיכול לשמש להזנת מחרוזת. מתחת ל-TextView שתעבד את הפלט, ולחצן שהמשתמש ילחץ עליו כדי להפעיל את הסיווג.
השלב הבא הוא כתיבת הקוד שיפעיל את ממשק המשתמש הזה.
4. מחברים את הפקדים ויוצרים את האפליקציה
כדי לערוך את הקוד של הפעילות הזו, צריך לחפש את קובץ הקוד של הפעילות הראשית.
- ב-Android Studio, לוחצים על אפליקציה > Java > MainActivity.
- כדי לעבור לעורך הקוד, פותחים את הקובץ MainActivity. החלפת כל מה שנמצא בקובץ הזה, חוץ מהשורה הראשונה שמתחילה ב-'package'. עם הקוד הזה:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class MainActivity : AppCompatActivity() {
lateinit var txtInput: EditText
lateinit var btnSendText: Button
lateinit var txtOutput: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
txtInput = findViewById(R.id.txtInput)
txtOutput = findViewById(R.id.txtOutput)
btnSendText = findViewById(R.id.btnSendText)
btnSendText.setOnClickListener {
var toSend:String = txtInput.text.toString()
txtOutput.text = toSend
}
}
}
הקוד הזה מחבר את הפקדים של הפריסה אל txtInput
, txtOutput
ו-btnSendText
כדי שניתן יהיה לטפל בהם בקוד. לאחר מכן היא מגדירה OnClickListener
ללחצן, כך שכאשר המשתמש נוגע בו, הטקסט מ-txtInput
ייקרא, יומר למחרוזת, ואז המאפיין txtOutput.text
יוגדר למחרוזת הזו.
5. יצירת האפליקציה הבסיסית ב-iOS
השלבים הבאים מחייבים היכרות מסוימת עם פיתוח Xcode ו-iOS עם Swift.
אם לא רוצים לבצע את תהליך היצירה, אפשר לשכפל את המאגר ולפתוח את האפליקציה ישירות. קוראים לו TextClassificationStep1 והוא נמצא בתיקייה iOS במאגר.
כדי ליצור את האפליקציה הבסיסית, צריך להתחיל ב-Xcode.
- יוצרים אפליקציה חדשה באמצעות התבנית הבסיסית:
- בוחרים אפשרויות לפרויקט החדש. נותנים למוצר שם ומזהה ארגון. אפשר להקליד את מה שרוצים או לפעול לפי הדוגמה הבאה: (עם זאת, הקפידו להגדיר את הממשק ל-Storyboard ואת מחזור החיים כ-UIKitApp Delegate, כפי שמוצג).
6. עריכת לוח הסיפור
- פותחים את Main.storyboard. תוצג לכם פלטפורמת עיצוב שאפשר להוסיף אליה פקדים.
- כדי להוסיף פקדים, לוחצים על הלחצן + בחלק העליון של חלון Xcode.
- התכונה הזו מאפשרת להציב פקד TextView, פקד לחצן ופקד Label (תווית) על משטח העיצוב. הוא אמור להיראות כך:
- משתמשים ב-Assistant כדי לפתוח תצוגה זה לצד זה כאשר הסטוריבורד והקבצים ViewController.swift פתוחים. העוזר הדיגיטלי הוא סמל קטן בפינה השמאלית העליונה של המסך, כמו בדוגמה הבאה:
- לוחצים על מקש Control וגוררים את הפקד TextView אל פלטפורמת הקוד. אתם אמורים לראות חץ כחול במהלך הגרירה.
- צונחים בקוד שמתחת להצהרה של הכיתה. ייפתח חלון קופץ שבו תתבקשו להזין את סוג החיבור. הוא אמור להיראות כך:
- בוחרים באפשרות Outlet ונותנים לה את השם txtInput.
- חוזרים על הפעולה הרצויה לתווית, ואז מגדירים את סוג החיבור כ-Outlet ונותנים לו את השם txtOutput.
- בסוף, גוררים את הלחצן כלפי מעלה, אבל הפעם בוחרים באפשרות פעולה בתור סוג החיבור. (אין להשתמש ב-Outlet כסוג החיבור).
- נותנים לפעולה את השם btnSendText.
בסיום התהליך, הקוד בחלק העליון של הכיתה אמור להיראות כך:
@IBOutlet weak var txtInput: UITextView!
@IBOutlet weak var txtOutput: UILabel!
@IBAction func btnSendText(_ sender: Any) {
}
7. סיום התכנות של האפליקציה הבסיסית ל-iOS
התצוגה הזו משתמשת ב-UITextView, ולכן כדי שהיא תגיב לאירועים בתצוגה הזו, היא צריכה להיות UITextViewDelegate.
כדי לעשות את זה, אפשר לשנות את ההצהרה לכיתה כך:
class ViewController: UIViewController, UITextViewDelegate {
לאחר מכן, בפונקציה viewDidLoad, מגדירים את ה-הענקת גישה ל-UITextView (שקראתם לו txtInput כשהגדרתם את השקע) למחלקה הזו, באופן הבא:
override func viewDidLoad() {
super.viewDidLoad()
txtInput.delegate = self
}
לבסוף, רוצים לטפל בהסרת המקלדת מהמסך אחרי שהמשתמש לוחץ על Enter במקלדת. התהליך מתבצע באמצעות הענקת הגישה שהגדרתם, ואפשר להטמיע את השיטה הזו ב-ViewController כדי לטפל בה.
func textView(_ textView: UITextView, shouldChangeTextIn range:
NSRange, replacementText text: String) -> Bool {
if (text == "\n") {
textView.resignFirstResponder()
return false
}
return true
}
באפליקציה הזו, פעולת הלחצן היא טריוויאלית, פשוט נעביר לפלט את מה שהמשתמש מקליד. בהמשך תראו איך מודל NLP יכול לסנן את הטקסט הזה. אבל בינתיים נעלה אותו כדי לדמות העברת זרם.
כבר יצרתם את הפעולה btnSendText, אז כל מה שצריך לעשות הוא להוסיף את הקוד הזה:
@IBAction func btnSendText(_ sender: Any) {
txtOutput.text = "Sent :" + txtInput.text
}
8. מעולה!
סיימת את ה-Codelab הזה!
בשלב הבא נלמד איך ליצור מודל NLP, ומחזירים מאוחר יותר את המודל הזה לאפליקציה כך שהיא תסנן את הטקסט של המשתמשים כדי לאתר תגובות ספאם.