1. 시작하기 전에
이 Codelab은 모바일 텍스트 분류 시작하기 개발자 과정의 활동 2입니다.
이 Codelab에서는 간단한 메시지 앱을 빌드합니다. 개발자 과정의 후반부에서는 앱의 메시지에서 원치 않는 스팸을 필터링하는 머신러닝 모델로 이 앱을 업데이트합니다.
기본 요건
- Kotlin을 사용한 Android 개발 및 (선택사항) Swift를 사용한 iOS 개발에 관한 기본 지식
빌드할 항목
- 간단한 메시지 앱
필요한 항목
- Android의 경우 시작하려면 Android 스튜디오가 필요합니다. 계속하기 전에 설치되어 있고 완전히 업데이트되었는지 확인하세요.
- iOS의 경우 Xcode가 필요합니다. App Store에서 찾을 수 있습니다. (iOS 앱만 작성하려면 5단계로 바로 건너뛰세요.
코드 가져오기
단계별로 진행하지 않고 이 개발자 과정의 최종 코드만 보려면
git clone https://github.com/googlecodelabs/odml-pathways
여기에서 TextClassificationOnMobile 디렉터리를 찾고 이 디렉터리 내에서 Android 및 iOS 하위 디렉터리를 확인합니다. 이러한 디렉터리에는 각각 Android 및 iOS의 앱이 포함된 TextClassificationStep1 하위 디렉터리가 포함됩니다.

2. Android 스튜디오에서 새 프로젝트 만들기
- Android 스튜디오를 시작합니다.

- 새 프로젝트 만들기 를 선택합니다. 프로젝트 템플릿을 선택하라는 대화상자가 표시됩니다.
- Empty Activity 를 선택하고 Next 를 클릭합니다. 다음으로 프로젝트를 구성하라는 메시지가 표시됩니다. 원하는 대로 선택하되 언어가 Kotlin이고 최소 SDK가 API 23인지 확인합니다.
- Finish 를 클릭합니다. 이 작업이 완료되면 Android 스튜디오가 프로젝트와 함께 열립니다. 특히 Android 스튜디오를 처음 사용하는 경우 모든 것이 제대로 작동하는지 확인하기 위해 Gradle 동기화를 실행하는 데 몇 분 정도 걸릴 수 있습니다.
3. 사용자 인터페이스 만들기
Android 앱의 사용자 인터페이스는 레이아웃 파일이라는 XML 파일을 사용하여 만들어집니다.
- 파일을 엽니다. Android 스튜디오의 탐색기를 사용하여 app > res > layout > activity_main.xml 을 클릭합니다.

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

다음 단계로 이동하기 전에 '코드'가 선택되어 있는지 확인합니다.
- 코드를 다음 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 코드 파일을 찾아 이 활동의 코드를 수정할 수 있습니다.
- Android 스튜디오에서 app > 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에 연결하여 코드에서 주소를 지정할 수 있도록 합니다. 그런 다음 사용자가 버튼을 터치하면 txtInput의 텍스트가 읽히고 문자열로 변환된 후 txtOutput.text 속성이 해당 문자열로 설정되도록 버튼의 OnClickListener를 설정합니다.
5. iOS에서 기본 앱 만들기
다음 단계에서는 Xcode 및 Swift를 사용한 iOS 개발에 익숙해야 합니다.
만들기 과정을 거치지 않으려면 저장소를 클론하고 앱을 직접 열면 됩니다. TextClassificationStep1이라고 하며 저장소의 iOS 폴더에 있습니다.
기본 앱을 만들려면 Xcode부터 시작합니다.
- 기본 템플릿을 사용하여 새 앱 을 만듭니다.

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

6. 스토리보드 수정
- Main.storyboard 를 엽니다. 컨트롤을 추가할 수 있는 디자인 화면이 표시됩니다.
- 컨트롤을 추가하려면 Xcode 창 상단의 + 버튼을 클릭합니다.

- 이를 사용하여 TextView 컨트롤, 버튼 컨트롤, 라벨 컨트롤을 디자인 화면에 배치합니다. 예를 들면 다음과 같습니다.

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

- CONTROL 키를 누른 상태에서 TextView 컨트롤을 코드 화면으로 드래그합니다. 드래그할 때 파란색 화살표가 표시됩니다.
- 클래스 선언 바로 아래의 코드에 놓습니다. 연결 유형을 묻는 팝업이 표시됩니다. 예를 들면 다음과 같습니다.

- Outlet 을 선택하고 txtInput이라는 이름을 지정합니다.
- 라벨에도 동일한 작업을 실행한 다음 연결 유형을 Outlet으로 만들고 txtOutput이라는 이름을 지정합니다.
- 마지막으로 버튼을 드래그하되 이번에는 연결 유형으로 Action 을 선택합니다. 연결 유형으로 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 모델을 만드는 방법을 알아봅니다. 이 모델은 나중에 이 앱으로 다시 가져와서 사용자의 텍스트에서 댓글 스팸을 필터링할 수 있도록 합니다.