레이블이 Mobile인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Mobile인 게시물을 표시합니다. 모든 게시물 표시

20150106

Swift 1.2 처음 써본 느낌

Xcode 6.3 베타 깔고 Swift 1.2 잠깐 만져봤다. 회사 iOS 프로젝트는 아직 Objective-C. 개인 프로젝트부터 시험.

1.1 → 1.2 가장 반가운 변경점은 빌드 속도. 체감이 달라짐. increment build 지원하고 whole module optimization도 들어옴. 1.1 시절엔 전체 재컴파일이 너무 자주 일어났었는데...

문법 변경도 몇 개 있는데 쓰면서 걸린 것:

1. asas!, as? 로 나눠짐. downcast할때 강제/옵셔널 구분이 명시적으로. 코드 마이그레이터 돌리면 자동으로 as!로 바꿔주는데 사실 대부분은 as? 쓰는게 안전.

// 1.1
let label = view as UILabel
// 1.2
let label = view as! UILabel   // 실패하면 crash
if let label = view as? UILabel { ... }

2. if let 체인 가능해짐. 이전엔 깊게 중첩해야 했는데:

if let a = optA, let b = optB, let c = optC where c > 0 {
    // 모두 unwrap
}

3. Set 타입이 표준 라이브러리에 추가. 드디어.

4. let 상수를 한번만 assign할 수 있게 됨 (lazy constant). 이 변경은 내 코드엔 별 영향 없었음.

Swift 전반 소감은 "objc 알아야 잘 쓸 수 있다" 는거. framework 자체가 objc로 된거라 optional unwrapping이나 nullable 표시가 여전히 어색한 부분 많음. 근데 문법 자체는 objc보다 훨씬 간결해서 앞으로 안쓸 수 없을듯. 회사 프로젝트도 1.2 안정화되면 mix해볼 생각.

20141217

Android 5.0 Material Design 적용 시작

Lollipop 나온 지 얼마 안됐는데 벌써 디자인팀이 Material 요구. minSdk는 여전히 14(ICS)라 support-v7 appcompat 21 써야 함. 같이 시작해본 메모.

appcompat-v7:21 쓰면 Toolbar가 들어옴. ActionBar 대신 Toolbar를 레이아웃에 직접 붙이는 방식. 처음엔 어색하지만 확실히 더 커스텀 자유도가 높다.

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

Activity에서:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

테마는 Theme.AppCompat.Light.NoActionBar 로 바꾸고 colorPrimary/colorPrimaryDark/colorAccent를 styles.xml에 정의. Lollipop 이상에선 상태바도 자동으로 colorPrimaryDark로 바뀜.

Ripple 효과는 21 이상만. selector 만들때 v21/ 디렉토리에 ripple 버전 따로 놓고, 하위 버전엔 기존 state_pressed selector 두면 됨. 매번 이렇게 폴더 두 벌 관리하는거 귀찮다.

CardView, RecyclerView도 이번에 같이 가져옴. RecyclerView는 ListView 후속인데 처음엔 onBindViewHolder/onCreateViewHolder 구조가 귀찮더라. 근데 사용하다보면 ViewHolder 강제라 성능 함정을 덜 만듦.

아직 디자이너랑 협의중인 부분: FAB(플로팅 버튼) 지원 라이브러리가 공식은 안나왔음. 서드파티 쓰거나 직접 만들어야 함. 내년에 디자인 서포트 라이브러리 나올 거라는 소문이 있긴 한데 일단 직접.

20140515

Android SQLite upgrade 전략

앱 업데이트하면서 SQLite 스키마 바꿔야 할 일이 또 생김. 그동안 매번 DROP/CREATE 했는데 이제 유저 데이터 유지 필요해서 제대로 마이그레이션 씀.

public class DbHelper extends SQLiteOpenHelper {
    private static final int DB_VERSION = 4;

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVer, int newVer) {
        if (oldVer < 2) {
            db.execSQL("ALTER TABLE item ADD COLUMN category TEXT");
        }
        if (oldVer < 3) {
            db.execSQL("CREATE TABLE favorite (id INTEGER PRIMARY KEY, item_id INTEGER)");
        }
        if (oldVer < 4) {
            // SQLite는 DROP COLUMN이 없다. 테이블 재생성...
            db.execSQL("CREATE TABLE item_new (id INTEGER PRIMARY KEY, title TEXT, category TEXT)");
            db.execSQL("INSERT INTO item_new SELECT id, title, category FROM item");
            db.execSQL("DROP TABLE item");
            db.execSQL("ALTER TABLE item_new RENAME TO item");
        }
    }
}

핵심은 if (oldVer < N) 블록을 누적으로 쌓는거. 버전 1 → 4로 한번에 올라오는 유저도 있으니까 각 단계 다 실행되게 해야 함.

SQLite 한계 몇가지:

  • DROP COLUMN 없음. 테이블 재생성 해야됨
  • PRAGMA foreign_keys는 연결마다 설정. onOpen()에서 매번 켜줘야 함
  • ALTER TABLE로 DEFAULT 바꾸는것도 안됨

migration 실수하면 유저 데이터 날아가서 리뷰테러 맞음. 꼭 이전 버전에서 업글 테스트 해야 함. 이전 apk 깔아서 데이터 넣고 → 새 apk로 업데이트 → 데이터 유지 확인. 귀찮은데 안하면 후회.

onDowngrade는 기본이 예외던짐. 내려가는 상황 없도록 스토어 롤백만 안 건드리면 됨.

20131119

Android 4.4 KitKat WebView 이슈 정리

KitKat 뜨고 테스트 단말 Nexus 5 샀는데 앱 WebView가 다 깨짐. 원인은 알다시피 Chromium 기반으로 바뀐거.

걸린 지점들 메모.

1. User-Agent 바뀜
// 4.3
Mozilla/5.0 (Linux; U; Android 4.3; ...) AppleWebKit/534.30 ...
// 4.4
Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/KRT16M) AppleWebKit/537.36 ... Chrome/30.0.0.0
서버에서 UA로 OS 분기하던 레거시 코드 몇 개가 오작동. "AppleWebKit/534"를 정규식으로 잡던 부분 다시 뜯어야 했다.

2. loadUrl("javascript:...") 가 void
그전엔 native에서 js 인보크하고 return value 못 받는걸 당연히 알고 있었는데, 4.4부터는 evaluateJavascript() 라는 새 API가 생겼음. callback으로 결과 받을 수 있음. 근데 4.4 미만에서는 안되니까 SDK 버전 분기 필요.

if (Build.VERSION.SDK_INT >= 19) {
    webView.evaluateJavascript("getToken()", new ValueCallback<String>() {
        public void onReceiveValue(String value) { ... }
    });
} else {
    webView.loadUrl("javascript:getToken()");
}

3. file:// 에서 XHR 막힘
로컬 html에서 json 불러오던게 CORS로 막힘. setAllowFileAccessFromFileURLs(true) 호출해야 되는데 보안상 찝찝함. 결국 assets 대신 서버에서 받아오는 쪽으로 바꿈.

기타 CSS viewport 계산이 살짝 달라져서 레이아웃 몇개 깨짐. 이건 일일이 잡는 수밖에...