기본 메시지 스타일 앱 빌드

1. 시작하기 전에

이 Codelab은 모바일 텍스트 분류 시작하기 개발자 과정의 활동 2입니다.

이 Codelab에서는 간단한 메시지 앱을 빌드합니다. 나중에 이 과정에서 앱의 메시지에서 원치 않는 스팸을 필터링하는 머신러닝 모델로 이 앱을 업데이트합니다.

기본 요건

  • Kotlin을 사용한 Android 개발 및 (선택사항) Swift를 사용한 iOS 개발에 관한 기본 지식

빌드할 항목

  • 간단한 메시지 앱

필요한 항목

  • Android의 경우 시작하려면 Android 스튜디오가 필요합니다. 계속하기 전에 SDK가 설치되어 있고 완전히 업데이트되었는지 확인하세요.
  • iOS의 경우 Xcode가 필요합니다. App Store에서 확인할 수 있습니다. iOS 앱만 작성하려면 5단계로 바로 건너뛰세요.

코드 가져오기

단계를 따르지 않고 이 경로의 최종 코드만 확인하려면 다음을 참고하세요.

git clone https://github.com/googlecodelabs/odml-pathways

여기에서 TextClassificationOnMobile 디렉터리를 찾고 그 안에 Android 및 iOS 하위 디렉터리가 표시됩니다. 이러한 디렉터리에는 각각 Android 및 iOS의 앱이 포함된 TextClassificationStep1 하위 디렉터리가 포함됩니다.

968cc631a448a8ef.png

2. Android 스튜디오에서 새 프로젝트 만들기

  1. Android 스튜디오를 시작합니다.

4542b16e14c33eed.png

  1. 새 프로젝트 만들기를 선택합니다. 프로젝트 템플릿을 선택하라는 대화상자가 표시됩니다.
  2. Empty Activity를 선택하고 Next를 클릭합니다. 다음으로 프로젝트를 구성하라는 메시지가 표시됩니다. 원하는 대로 선택하되 언어는 Kotlin, 최소 SDK는 API 23이어야 합니다.
  3. 마침을 클릭합니다. 이 작업이 완료되면 Android 스튜디오가 프로젝트와 함께 열립니다. 특히 Android 스튜디오를 처음 사용하는 경우 모든 항목이 올바른지 확인하기 위해 Gradle 동기화를 실행하는 데 잠시 시간이 걸릴 수 있습니다.

3. 사용자 인터페이스 만들기

Android 앱의 사용자 인터페이스는 레이아웃 파일이라는 XML 파일을 사용하여 생성됩니다.

  1. 파일을 엽니다. Android 스튜디오의 탐색기를 사용하여 app > res > layout > activity_main.xml을 클릭합니다.

562f935ccaa9e666.png

화면 오른쪽 상단에 다음과 같이 코드, 분할, 디자인 탭이 있는 선택 항목이 표시됩니다.

3ae858bfe4ec100f.png

다음 단계로 이동하기 전에 '코드'가 선택되어 있는지 확인합니다.

  1. 코드를 다음 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가 있는 입력 영역과 문자열을 입력하는 데 사용할 수 있는 txtInput이라는 EditText가 포함된 기본 사용자 인터페이스가 제공됩니다. 아래에는 출력을 렌더링하는 TextView와 사용자가 분류를 트리거하기 위해 누르는 버튼이 있습니다.

다음 단계는 이 사용자 인터페이스를 활성화하는 코드를 작성하는 것입니다.

4. 컨트롤 연결 및 앱 만들기

MainActivity 코드 파일을 찾아 이 활동의 코드를 수정할 수 있습니다.

  1. Android 스튜디오에서 app > java > MainActivity를 클릭합니다.

c633c2293d0835b8.png

  1. 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에 연결하여 코드에서 처리할 수 있도록 합니다. 그런 다음 사용자가 버튼을 터치할 때 txtInput의 텍스트가 읽히고, 문자열로 변환된 후 txtOutput.text 속성이 해당 문자열로 설정되도록 버튼의 OnClickListener를 설정합니다.

5. iOS에서 기본 앱 만들기

다음 단계를 수행하려면 Xcode와 Swift를 사용한 iOS 개발에 익숙해야 합니다.

생성 과정을 거치고 싶지 않다면 저장소를 클론하고 앱을 직접 열면 됩니다. 이름은 TextClassificationStep1이며 저장소의 iOS 폴더에 있습니다.

기본 앱을 만들려면 Xcode로 시작합니다.

  1. 기본 템플릿을 사용하여 새 을 만듭니다.

254c026ac66e32f9.png

  1. 새 프로젝트의 옵션을 선택합니다. 제품에 이름조직 식별자를 지정합니다. 원하는 내용을 입력하거나 아래 예시를 따를 수 있습니다. 하지만 표시된 대로 인터페이스를 Storyboard로, 수명 주기를 UIKitApp Delegate로 설정해야 합니다.

d0bd704bfa657d5f.png

6. 스토리보드 수정

  1. Main.storyboard를 엽니다. 컨트롤을 추가할 수 있는 디자인 화면이 표시됩니다.
  2. 컨트롤을 추가하려면 Xcode 창 상단의 + 버튼을 클릭합니다.

a5203e9757e6b11e.png

  1. 이를 사용하여 TextView 컨트롤, Button 컨트롤, Label 컨트롤을 디자인 화면에 배치합니다. 예를 들면 다음과 같습니다.

13d02aae8d8c4a13.png

  1. 어시스턴트를 사용하여 스토리보드와 ViewController.swift 파일이 모두 열린 나란히 보기 모드를 엽니다. 어시스턴트는 화면 오른쪽 상단에 있는 작은 아이콘입니다(아래 참고).

d152cce014151f26.png

  1. CONTROL 키를 누르고 TextView 컨트롤을 코드 화면으로 드래그합니다. 드래그하면 파란색 화살표가 표시됩니다.
  2. 클래스 선언 바로 아래의 코드에 드롭합니다. 연결 유형을 묻는 팝업이 표시됩니다. 예를 들면 다음과 같습니다.

455b8b131e5f3b3d.png

  1. 아울렛을 선택하고 txtInput이라는 이름을 지정합니다.
  2. 라벨에도 동일한 작업을 수행한 다음 연결 유형을 Outlet으로 설정하고 txtOutput이라는 이름을 지정합니다.
  3. 마지막으로 버튼을 드래그하지만 이번에는 연결 유형으로 작업을 선택합니다. (콘센트를 연결 유형으로 사용하지 마세요.)
  4. 작업 이름을 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 모델을 만드는 방법을 알아봅니다. 이 모델은 나중에 이 앱으로 다시 가져와 사용자의 텍스트에서 댓글 스팸을 필터링하는 데 사용됩니다.