이번 학기에 시작한 안드로이드 개발 수업! 아직 아무것도 모르겠고 어색하지만 언제나 그래왔듯 다시 한번 시작해보겠다.

 

원래 나는 무언가를 배우기 시작할때 이론적인것부터 들이밀고 공부하라고 하면 진절머리가 나는 스타일이다. 직접 간단한 앱을 만들면서 차근차근 더 깊이 배워보도록 하겠다.

 

사용 언어는 Kotlin을 사용하고, 코틀린은 자바에 대한 이해가 있으면 코딩하기가 좀 더 수월할거라고 들었다. 다행히 자료구조 알고리즘을 자바로 배운터라 크게 걱정하진 않았다. 앱을 만드는데 쓰는 프로그램은 Android Studio를 썼고, Mac M1 pro에서 사용중이다. 이번에 만들어볼 앱은 정말 간단한 퀴즈 맵이다. 문제가 나오고 True/ False를 선택 할 수 있는 앱이다. 한번 시작해보자!

 

먼저, Android Studio를 실행하고 New Project(Empty)를 누르면 아래와 같은 창이 나온다.

 

중요한 태그 몇개만 짚고 넘어가겠다.

 

  • Name : 말 그대로 "앱 이름" 이다. 여기서는GeoQuiz라고 칭하겠다.
  • Language : 사용 언어는 위에서 말했듯 코틀린이다.
  • Minimum SDK(최소 지원 API레벨) : 이건 현재 만드려는 앱이 어디까지 지원 할 수 있는지를 나타내는 좌표인데, API뒤의 숫자가 커질수록 최신 API이며, 그만큼 현존하는 기기들과 호환되지 않는 경우가 많다. 일반적으로는 낮은 API를 사용한다.

 

그 다음, 이러한 창이 나오면 왼쪽 아래 망치버튼을 누르면 콘솔에 알 수 없는 명령어들이 나오면서 BUILD SUCCESSFUL이라는 문구가 뜬다.

 

 

왼쪽 위에 보면, project view를 설정 할 수 있는데, Android Studio의 디폴트 view는 Android view이다[개발자들이 디폴트값을 이렇게 설정 해놓은데에는 항상 이유가 있다]. Android view는 실제 진행하는 프로젝트의 디렉토리를 숨겨 우리가 현재 진행중인 안드로이드 프로젝트에만 더 집중 할 수 있도록 해준다.

 

Android view와 Project view의 차이

한눈에 봐도 왼쪽이 훨씬 더 간결해보인다.

 

그 다음, 아래와 같이 Empty Views Activity를 누른다. 되게 복잡해 보이고 처음 해보는 사람들은 헷갈리겠지만, 지금은 하나하나가 뭔지 알 필요 없다!

 

 

 

그러면 아래와 같이 처음 보는 코드들이 보일것이다. 

 

이제, 안드로이드에게 앱을 시작할때 화면에 무엇을 로드할지 알려주어야 한다. [UI 레이아웃]

 

 

그 다음, 왼쪽 에디터에 보이는 AndroidManifest.xml파일을 연다. 그러면 처음 보는 코드들이 쓰여있는데, 거기서 <activity/> 태그로 감싸진 부분을 수정해준다. 디폴트는 아래와 같지만

 

<activity
    android:name=".MainActivity"
    android:exported="false" />

 

 

다음과 같도록 수정해준다

 

<activity
    android:name=".MainActivity"
    android:exported="true">
<intent-filter>
    <action android:name="android.intent.action.MAIN" />

    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

 

간단히 짚고 넘어가자면, android : exported = "false"에서 "true"로 변경한 부분과 <intent-filter>부분은 앱에게 "앱을 실행하면 MainActivity가 보여질것" 이라고 변경해준것과 같다.

 

 

다음은 app/res/layout/activity_main.xml  을 열고, 코드를 보면 디폴트 값으로 되어있는데, 이 디폴트 코드들을 아래와 같이 변경해준다.

 <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

기본 값은 두가지 view가 있다. Constraint layout과 TextView. 아래는 두가지를 간단히 표현한 그림이다.

 

 

그런데 우리가 만들 앱은 단순히 텍스트 뷰만 있어서는 안된다. 우리가 만들 앱의 MainActivity는 더 많은 view들이 필요하다.

  • a vertical LinearLayout
  • a TextView
  • a horizontal LinearLayout
  • two Buttons

추가적으로 필요한 view들을 나타낸 모습

그러면 나머지 필요한 view들을 activity_main.xml파일에 추가해주자. 원래 있던 코드들은 모두 지워주고 아래처럼 작성하면 된다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp"
        android:text="@string/question_text" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button" />

    </LinearLayout>

</LinearLayout>

 

뭔가 서식들이 전에 웹 프론트엔드를 공부할때 css에서 봤던것들과 비슷해보인다.

 

그런데 여기서 문제가 하나 생긴다. 위의 코드를 작성하면 오른쪽 위에 IDE Warning이 뜰것이다. 버튼에 대한 warning인데, 여러 버튼들이 horizontal layout에 인접해 있으면 뜨는 오류이다. 해결 방법은 간단하다. 버튼 태그 안에 style="?android:buttonStyle" 만 추가해주면 된다.

 

코드를 살펴보면 Textview, Button 는 android : text라는 속성이 있다. 이 속성은 view에게 어떤 텍스트를 보여줄건지 명령하는 속성이다. 하지만 여기서 중요한 부분이 있다. 이 text속성의 값은 raw 문자열이 아닌 대신에, @string/ syntax를 이용하여 string값을 참조해야 한다. 단순히 hardcoding으로 android : text = "True" 라고 할 수 있지만, 하드코딩은 좋은 방법이 아니다(유지보수 문제). 대신 문자열을 별도의 파일에 넣고 참조하는것이 좋은 방법이다.

 

자 그럼 이제, 참조할 문자열 파일을 만들어보자!

 

모든 프로젝트는 디폴트 문자열 파일 res/values/strings.xml 이 포함되어있다. 이 파일을 열고, 우리가 view에 전달해야 할 문자열을 MainAcrtivity가 참조 할 수 있도록 문자열을 추가해주자.

 

strings.xml파일에 문자열을 더한 모습

문자열 파일은 이름이 꼭 strings가 아니여도 되고, 여러가지 문자열 파일을 만들수도 있다.(단, 무조건 res라는 상위폴더 아래에 만들어야 한다) 각 분야마다 문자열 파일을 따로 만들어 놓는다면(직관적인 문자열 파일 이름과 함께) 유지보수가 더욱 더 쉬워질 것이다.

 

그다음 이제 다시 activity_main으로 돌아가 preview를 본다면 

 

 

짜잔! 우리가 원하는 모습이 되어있다.

 

포스팅이 너무 길어지므로 다음 포스트에서 이어가도록 하겠다!

이번에는 Swift를 가지고 여러가지 문법이나 사칙연산들을 하면서 놀 수 있는 Playground 대신, 실제 프로젝트를 하나 만들어보겠다.

 

먼저, XCode를 실행하면 다음과 같이 보일것이다.

 

XCode를 실행한 후의 모습

 

이제 프로젝트를 생성할건데, Create New Project를 눌러준다. 그러면 템플릿을 고를 수 있는 창이 뜨는데, 우리는 기본 IOS앱을 개발하는중이므로 그냥 App을 누르고 Next를 한다.

 

그러면 다음과 같은 창이 보일것이다.

 

 

이전 포스트에서 설명했듯, Product Name은 앱의 이름이고, Bundle Identifier는 앱스토어에서 각 앱마다 고유하게 가지는 식별자 역할을 한다. 어쨌든... 나머지는 일단 지금은 크게 신경쓰지 않아도 된다. 어차피 막 배우기 시작한 사람들이고 Swift가 뭔지, XCode로 코딩을 어떻게 하는지정도의 느낌만 줄 수 있다면 그걸로 만족한다.

 

Next를 누르고 프로젝트 폴더를 원하는 경로에 만든다.

 

그러면 이제 아래와 같이 생긴 화면이 뜰텐데, 왼쪽의 프로젝트 네비게이터에서 Main파일을 더블클릭하면 우리가 항상 보는 휴대폰 화면이 컴퓨터 화면에 뜬다!

 

 

 

 

자 그러면 이제 저 아이폰 모양의 스크린에 글자를 띄워보고싶다고 해보자.

 

 

오른쪽 상단 부분의 + 버튼을 누르면 앱에 넣을 수 있는 여러가지 attribute들이 있다. 버튼, 드롭다운 박스, 유저로부터 입력값을 받는 place holder등등 여러가지가 있다. 여기서 우리는 글자를 일단 넣어보고싶으므로 Label을 선택하고[드래그해서 아이폰 화면에다가 갖다 붙이면 된다!] Hello Swift라는 글자를 입력한다.

 

그런데 글자 크기가 너무 작고, 왼쪽에 붙어서 alignment된 텍스트 덩어리를 화면의 정중앙에 위치시키고 글씨체를 바꾸려면 어떻게 해야할까?

 

일단 방금 추가한 텍스트 단락을 마우스로 왼쪽 클릭한 후 아래 화면 오른쪽 위에 보이는 세개의 화살표를 누르면 Inspector가 나타날것이다. 거기서 글씨체, 글자의 위치 등등 여러가지를 조정할 수 있다.

 

 

 

 

이제 다음으로 사용자로부터 입력값을 받는 TextField와 버튼을 하나 넣어서 TextField에 입력값을 받고 그 버튼을 누르면 Hello Swift의 텍스트가 바뀌도록 해보겠다.

 

일단 버튼과 TextField를 넣은 후의 모습은 다음과 같다.

 

위에서 설명한 기능을 실행하려면 먼저 코드와 UI를 연결해야한다.

 

아래처럼 맨 왼쪽의 네비게이터에서 ViewController에 마우스를 올리고 option키를 누른 상태에서 클릭을 하면 창이 두개로 나뉜다. 사실 이 창을 두개로 나누는 과정은 코드와 UI연결에는 아무 연관이 없지만, 두 편집기를 동시에 켜놓고 보면 훨씬 더 개발하기가 수월해질것이다.

 

 

 

 

이제 어떻게 저 UI와 코드를 연결하는지 살펴보자.

 

일단 첫째로 우리의 목적(Hello Swift)라벨이 입력값에 따라 바뀌는것이다. 그럼, Hello Swift 라벨을 오른쪽 클릭하고 컨트롤 키를 누른 후 오른쪽 소스코드가 있는 편집기의 14번째줄에 드래그를 해보자(생각보다 간단하다). 그러면 이름을 지정하라는 Name이 보일건데, 여기다가는 저 Hello Swift라벨을 식별할수 있는 이름을 지어주는것이다. 그냥 변수를 지정해준다고 생각하면 더 이해하기 쉬울것이다.

 

드래그를 하고 나면 이렇게 코드가 자동으로 붙여진다.

나는 위의 이름 지정에서 Label이라는 이름을 붙여줬고, 아래 코드에서 보이듯이 var Label 이라는 변수가 생성되었다. 아직 열정만 넘치는 주니어 개발자 지망생이지만 코드를 쓰기 전에 머릿속에서 생각한 로직이 들어맞을때의 쾌감은 말 할 수 없다!

@IBOutlet weak var Label: UILabel!

 

 

같은 방법으로 텍스트 필드, 버튼 필드들을 모두 연결해보자.

 

위의 과정들을 문제없이 따랐다면 아래와 같이 보일것이다.

import UIKit

class ViewController: UIViewController {

    
    
    @IBOutlet weak var Label: UILabel!
    
    
    @IBOutlet weak var Text: UITextField!
    
  
    @IBAction func Button(_ sender: Any) {
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


}

 

뭔가 이상한점을 발견했다. 입력값을 받는 텍스트필드와 글자가 바뀌는 라벨은 Outlet이라는 태그로 변수가 생성되었는데, 버튼은 Action이라는 태그로 변수가 생성되었다. 그러면 각각 두개는 무엇을 의미할까?

 

  • Outlet : 입력한 값을 코드로 가져오거나, 코드에서 속성을 바꾸고 싶을때 Outlet으로 연결한다.
  • Action : 간단히 말해 특정 동작을 trigger 시키는 요소에는 Action 태그를 지정해준다.
  • 참고 : : Outlet은 reference로 연결되고, Action은 함수로 연결된다.

일단 지금은 함수 안의 내용을 몰라도 되니 이해가 안되더라도 그냥 넘어가도 좋다. 코드를 많이 써본 사람이라면 보자마자 뭔가 느낌상 이 코드가 왜 이렇게 쓰였는지 보일것이다.

 

 

 

 

 

 

이제, 결과물을 보기 위해 왼쪽 상단부분에 플레이 버튼을 눌러 프로젝트를 실행시켜보자.

결과물이다! 정말 보잘것 없는 미비한 프로젝트이지만 그래도 기분은 좋다. 내 생에 첫 Swift를 통해 내가 원하는대로 동작하는 무언갈 만들어냈다!

'IOS' 카테고리의 다른 글

XCode와 Swift를 이용한 IOS앱 개발 첫 걸음마 떼기  (0) 2024.01.17
IOS 앱 개발 수업을 들으며  (0) 2024.01.17

+ Recent posts