한 2년 가까이 iOS 프로그램을 안만들었더니...세월이 넘 빠르게 흘러버렸는지 도데체 감이 안온다.

그 사이에 swift도 나왔고, iWatch도 나오고, 그리고 얼마전에는 Metal도 공개되었다.

이것저것 바뀐게 꽤 많은데, 계속 follow-up을 하지 않으니 뭐가 나왔다더라 이상은 모르는 게 사실.


대부분의 국내 기업들이 안드로이드나 하이브리드 방식으로 앱을 개발하는 관계로 꽤 오랫동안 본의아니게 등안 시 했었는데, 이러다가 iOS 다 잊어버리겠다는 생각이 들어서 하루에 조금씩 다시 관련 내용들을 살펴보기로 했다.


아무튼, 오픈 소스 컨트롤러 몇 개를 검색해보다보니 대부분의 소스들이 CocoaPod 를 통해서 개별 프로젝트에 라이브러리를 따로따로 파편화되는 것은 방지하고, repository를 통해서 관리하고, 팀 간 협업을 지원할 수 있으며, 간편하게 새로운 버전 또는 공동 작업 버전의 오프소스를 관리 및 업데이트할 수 있다고 한다.


CocoaPod 홈 - https://cocoapods.org



Ant, Maven이나 Gradle과 같은 빌드자동화 툴인지는 아니지만, 일부 기능이 일맥상통하는 부분이 있다.


Apache Ant는 빌드자동화 툴로 많이 알려졌고, xml 기반의 빌드 스크립트가 커지고 dependency 이슈로 인해서 이를 관리하기 힘들어져 나중에 Apache IVY를 추가하게 되었다고 한다.


Maven의 경우는 Ant의 이러한 문제점을 해결하기 위해서 나왔지만 여전히 xml에 사양을 기재하는 방식이다. 하지만 기존의 Ant가 빌드에 필요한 모든 커맨드들을 모두 기재해야 했다면, Maven은 규약들과 invoke 해야할 타겟을 지정하는 형태로 사용하기 때문에 Ant와는 큰 차이가 있다고 한다. 더 가볍고, 라이브러리의 버전 및 프로젝트 관리가 더 편한 Maven도 라이브러리의 dependency 관리에 이슈가 있다고 한다.(Ant는 라이브러리의 dependency를 Apache IVY 추가를 통해서 보완했다)


아무튼 이 와중에 Gradle이 2012년에 나왔고, 구글이 이를 안드로이드 배포 패키지 관리를 위한 빌드자동화툴로 선택하며서 많이 퍼지게 되었다. 아주 빠른 속도로 이 툴은 선택되었다.


Gradle 역시 Maven과 같이 필드와 라이브러리 관리를 모두 지원하며, Ant의 강력함과 유연성 그리고 Maven의 라이프사이클 관리와 사용 편리성을 모두 갖췄다고 한다. 기존의 XML을 통한 방식보다는 Groovy 언어 기반의 DSL(Domain Specific Language)을 이용한다. 그 결과 Ant나 Maven 보다 더 읽기 쉽고, 간단한 빌드 사양을 작성할 수 있다. 처음에 Apache IVY를 dependency 관리 툴로 사용했지만 나중에 자체 관리기능으로 변경했다고 한다.


*. 참조해서 읽은 글 - http://technologyconversations.com/2014/06/18/build-tools/


- Ant: https://en.wikipedia.org/wiki/Apache_Ant

- Maven: https://en.wikipedia.org/wiki/Apache_Maven

- Gradle: https://en.wikipedia.org/wiki/Gradle

- DSL: https://en.wikipedia.org/wiki/Domain-specific_language



아무튼, 또 쓰잘데기 없이 '이게 뭔가?'해서 문서들을 이것저것 읽어댔는데...


이런 빌드자동화 툴보다는 사용법은 NPM과 같은 비슷하면서 Mac 개발환경 하의 라이브러리 dependency 관리 및 프로젝트 관리에  도움을 주는 일종의 툴로 보면 될 것 같다. 


지금 떠오르는 장점을 좀 생각해보자면, 이 정도일 것 같다.


1) 라이브러리의 중복을 제거한다.

2) 라이브러리의 버전을 관리한다.

3) 팀 프로젝트의 형상관리 시 동일한 버전의 라이브러리를 운영한다.


그럼, 한 번 설치해보자.



1. CocoaPod의 설치


CocoaPod는 루비(Ruby)로 만들어졌다고 한다. OS X의 기본 설치된 루비를 이용하면 된다고 하는데, 루비 버전은 그냥 신경쓰지말라고 그냥 아래의 명령어를 입력하여 설치하면 된다고 한다.


설치 가이드 - https://guides.cocoapods.org/using/getting-started.html#getting-started



$ sudo gem install cocoapods



관리자 권한으로 명령어를 입력하면, 비밀번호 확인하고 설치가 한참있다가 시작된다. 

잠시 뭔가 이상이 생긴것이 아닌가라는 생각이 들정도로 딜레이가 있다.



내 경우에는 1분이 넘어서 아래와 같이 설치 및 완료를 볼 수 있었다.



설치 가이드 밑에 보면 sudo 권한을 통하지 않고, 설치하는 방법도 나와있으므로 참고해서 설치하고 싶은면 따라하면 될 것 같다.


설치할 때 가끔 이슈가 발생하기도 하나 보다. 그럴 경우에는 다음의 페이지를 참조해서 해당 이슈를 해결해보자.


트러블슈팅 - https://guides.cocoapods.org/using/troubleshooting#installing-cocoapods



2. CocoaPod를 통한 프로젝트 설정


간단하게 프로젝트 설정을 다음의 오픈소스를 가지고 진행해보았다.


https://github.com/jdg/MBProgressHUD




원피스 캐릭터 스티커 줘서 좋기는 한데...왜 니코 로빈은 안나오는 거야!!


검은 머리의 니코 로빈을 내놓아라.


체크 면티에 스웨터나 스웨터 조끼를 입은 니코로빈을 내놓아라!

 



비 쫄딱 맞고 와서 내 방에 와서 등짝을 꾹꾹이 해주는 까탈이. ㅋㅋㅋ


목욕시킬려고 하면 난리가 난다.


애교 덩어리. ㅎㅎㅎ



외쳐! 탑아! ㅋㅋㅋ



시즌 끝까지 쭈욱 이어졌으면...

안드로이드 하이브리드 앱을 만들 때 앱과 웹의 구분을 하고 싶어하는 경우가 있다.


언제 앱에서 오고, 언제 웹에서 오는 지 어떻게 구분하는 걸까?


생각해보니 보통은 제품을 사용하니까 제품에서 특정 스크립트를 제공하거나 통신 시에 앱에서만 특정한 정보를 전달하는 경우가 있는데...제품을 사용하지 않고, 그냥 하려면 어떻게 하는 게 좋을까하고 조금 생각해보았다.


그래서 든 생각이 앱에서 http request를 던질 때 header를 커스텀하는 것이 생각나서 해봤는데, 꽤나 괜찮은 방법이었다.


그래서 열심히 검색 -> http://stackoverflow.com/questions/7610790/add-custom-headers-to-webview-resource-requests-android



 WebView  host = (WebView)this.findViewById(R.id.webView);
 String url = "<yoururladdress>";

 Map <String, String> extraHeaders = new HashMap<String, String>();
 extraHeaders.put("Authorization","Bearer"); 
 host.loadUrl(url,extraHeaders);


키밸류를 가지는 해쉬맵을 하나 만들어서 헤더에 추가하는 방법이다. (API Level 8 부터 지원한다)


앱에서만 이 정보가 넘어오므로, 서버에서는 해당 정보를 보내는 녀석만 앱으로 인식하면 된다.



응? 그런데 무엇인가 이상하다...어떤 폰은 잘 되는데, 어떤 폰은 서버에서 그런 키가 없다고 한다.


무엇이 문제란 말인가???


헤더를 읽어보니 크로미움을 적용하는 킷캣부터는 헤더의 키 값이 모두 소문자로 보내진다.


아항...그렇구나.


그럼 소문자로 키와 밸류를 별도로 적용하기로 한다.


안드로이드 젤리빈까지는 헤더에 값을 넣은대로 서버에서 헤더가 인식되는데, 킷캣부터는 내가 커스텀한 헤더의 정보는 모두 소문자로 들어가는 이슈가 있었던 것.


이걸로 잠시 삽질을 했다.


바나나가 들어 있어면 왠지 마셔보고 싶다.



안드로이드 킷캣(4.4 / API 19)부터 애플리케이션 내에서 이미지와 문서를 바로 프린트하는 기능을 제공한다.


프린트하는 기능들은 Android Support Library를 통해서 가능한데, V4 support library의 PrintHelper 클래스를 이용하면 쉽게 앱에서 이미지, html, 커스텀 문서의 프린터 출력을 할 수 있다.


참고 - http://developer.android.com/training/printing/index.html

동영상 - https://www.youtube.com/watch?v=Iub67ic87KI



구글의 가이드를 보니 꽤 쉬워보여서 예제 코드 넣고 바로 실행!


안드로이드 Android Support Library를 Android tools > Add Support Library… 통해서 추가하여 android-support-v4.jar 가 libs 폴더에 추가되었음에도 불구하고 정상적으로 라이브러리를 찾지 못했다.

이에 build path에서 private library에 체크가 안됐나? 하고 열어보니 체크가 되어 있다.
(Android Support Library rev 22 부터 private과 dependencies에 담기는 라이브러리 나눠짐)

이것은 미스터리…우째 이런 일이?

지금 사용하는 이클립스에 안드로이드 안드로이드 SDK 툴과 support library를 계속 업데이트하면서 Android SDK tools rev 21인가 22 업데이트 꼬여서 고생한 적이 있었는데…자꾸 그 생각이 난다.

아무튼, 해결 방법은 좀 당황스럽지만 v4 샘플 코드 프로젝트를 import해서 라이브러리를 직접 카피해서 프로젝트에 넣었더니 모두 잘된다. 헐…뭐야 이게.


어찌됐든 프린트는 잘 된다는 것이고, 다음과 같은 조건에서 프린트할 수 있다.


1) 네트워크 프린터의 경우 동일 네트워크에 프린터가 있을 경우 (일반 네트워크 프린터)

2) WiFi Direct 설정을 통해서 연동시킨 프린터가 있을 경우 (WPS 지원 프린터)

3) NFC 태그 프린팅을 지원하는 프린터가 있을 경우 (자체 프로그램을 사용할 수도 있음)


요즘 시중에 WPS 지원 프린터로 모바일 디바이스와 다이렉트로 연결할 수 있는 장비들이 나오고 있으니 그걸 이용하면 그냥 프린트할 수 있는데, 단말과 계속 붙이고 있으면 배터리가 빨리 줄어드는 것 같다. (배터리...배터리...모바일은 배터리)


프린터 사용할 때에만 연결하여 사용하면 될 것 같다.



날짜나 시간을 가져오기 위해서 어떤 방법이 있는 지 검색해봤다.


일단 날짜를 출력하기 위해서는 달력이 어떻게 되어 있는지, 시간이 어떻게 측정(?)되는 지 알아야 할 것 같아서 좀 더 검색을 해봤다.


출처 - http://bomber0.byus.net/index.php/2009/02/05/983


천체관측을 통해서 1년을 365일 5시간 48분 55초라고 하는데, 보니 365일과 약 1/4일이 1년이라는 이야기다.


4년 마다 약 하루씩의 날짜가 더 있기 때문에, 4년마다 윤년을 두고 2월에 하루를 더 추가하지만,  33년 마다 8일이 더 붙어서 100 = 33 * 3 + 1 , 400 = 33 * 3 * 4 + 4 라는 식을 활용한다면, 400년에는 8 * 3* 4 + 1 =97 일 정도가 더 필요해지게 되고, 이 오차를 수정하기 위해서 100년 마다 윤년을 건너뛰고 400년의 배수가 되는 해를 윤년으로 해서 100년간 97번의 윤년을 가지게 된다고 한다.


출처 - http://stackoverflow.com/questions/5369682/get-current-time-and-date-on-android

율리우스력 - http://en.wikipedia.org/wiki/Julian_calendar

그레고리력 - http://en.wikipedia.org/wiki/Gregorian_calendar


4년마다 율리우스력을 사용하던 방식에서 16세기 그레고리 교황 시기에 이 오차를 수정한 그레고리력을 사용을 시작했고, 댓글을 보니 1582년 10월 4일에서 1582년 10월 15일로 10일을 점프(기존 오차를 보정?)해서 적용했다고 한다.


아무튼 그렇다고 하니 그렇다.



안드로이드에서 시간을 얻는 방법을 좀 검색해보니 방법이 꽤 많다.


조 - http://developer.android.com/reference/android/os/SystemClock.html


우선 안드로이드의 시스템 시간을 얻어오는 방법들을 알아봤다.


안드로이드 시스템 시계는 android.os.SystemClock 클래스를 통해서 이용할 수 있는데, 몇 가지 특성이 있다.


1) System.currentTimeMillis()
System.currentTimeMillis()는 표준적인 시계로, 특정 시점(1970년 1월 1일 00:00:00.000)을 기준으로 현재의 시간을 밀리 초로 표시하는 시계로 데이터 타입은 long 이다. 

UTC(협정 세계시) 기준으로 사용자가 직접 시스템 시간을 설정하거나 네트워크 시간 받아오기를 선택함으로써 해당 시간을 시스템의 현재 시간으로 인지한다. (따라서 사용자가 현재와 다른 시간을 수동으로 설정하거나 장시간 네트워크가 끊어짐으로 오차가 발생할 여지는 있을 것 같다.)

이 시계는 캘린더 알람과 같은 앱에서 사용될 때 실제 시간과 일치하여 사용되기도 하고, 타임스탬프와 같은 항목에 적용할 수 있다고 한다. (음, 캘린더나 알람 등 실제 생활과 연결이 되는 앱을 만들때에는 현재의 시간이 네트워크를 통하여 동기화되어 있나를 체크해보는 것이 필요할 것이라는 생각이 든다.)

사실 별 생각없이 사용했는데, 그렇구나 하는 게 있다.


2) uptimeMillis()
uptimeMillis()는 시스템이 부팅된 이후의 시간을 밀리초로 표시하는 시계로, SystemClock.uptimeMillis()와 같이 사용되며 데이터 타입은 long 이다.

요 녀석의 특징은 시스템이 잠들면 시간이 멈춘다는 점이 특징이다. 잠든다고 표현한 항목들은 CPU의 off 상태, 화면이 꺼져서 검게된 상태, 그리고 외부 입력으로 인하여 시스템이 대기중인 상태 등이다. 그 외에 전력을 아끼기 위해서 화면이 어두워지거나 하는 등의 절전 상태에서는 이 시계는 잠들지 않는다.

이런 특징을 가지고 있기 때문에 앱이 실행 중인 상태에서 실행 시간 등을 체크하는 데 사용하면 될 것 같다. 예를 들면 게임에서 플레이 타임을 체크할 때 유용하지 않을까 생각이 든다.


3) elapsedRealtime(), elapsedRealtimeNanos()

이 녀석들은 시스템 부팅 이후 앱이나 시스템의 대기상태 등에 영향을 받지 않고 계속 시간을 체크하며, long 타입을 반환한다.


uptimeMillis()가 상태에 따른 시간의 흐름이 단절되는데 반해서 시스템 부팅 이후의 시간을 계속 체크하므로, 일반적인 목적의 시간 간격을 체크하는 기반으로 사용되면 좋다고 한다.



그 외에도 좀 읽을 거리가 많이 있기 때문에 위의 구글 주소에 들어가서 한 번 읽어보면 좋을 것 같다.





안드로이드 단말이 대개 하드웨어 키가 있는 것하고, 소프트 키가 있는데...레이아웃이 맞지 않는 경우가 종종 있다.

그래서, RelativeLayout으로 위젯들을 배치하는 것도 괜찮지만 아무래도 전체 화면을 모두 동일하게 사용하고 싶은 경우가 발생한다.


안드로이드 4.0 이후(API Level 14)부터 하단 네비게이션 바(Navigation bar)와 상단의 상태바(Status bar)를 감추는 옵션을 제공했다. 

킷캣(API Level 19)부터는 Immersive mode를 제공한다.


관련 URL - https://developer.android.com/training/system-ui/immersive.html


네비바와 상태바를 사용자의 화면 상단을 끌어서 표시하고, 터치로 감추려면 다음과 같이 하면 된다.



public void onWindowFocusChanged(boolean hasFocus) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  

if (hasFocus) {

getWindow().getDecorView().setSystemUiVisibility(

View.SYSTEM_UI_FLAG_LAYOUT_STABLE

| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

| View.SYSTEM_UI_FLAG_FULLSCREEN

| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

}

}

}

 



맥에서 백그라운드로 실행되는 데몬과 에이전트를 lauchd 라는 launchctl 제품이 있다고 한다.


아무튼 기본 사용법은 간단하다.


FTP 서비스 시작 >

sudo -s launchctl load -w /System/Library/LaunchDaemons/ftp.plist


FTP 서비스 종료 > 

sudo -s launchctl unload -w /System/Library/LaunchDaemons/ftp.plist


이렇게 시작하면 일단 사용자 계정의 루트로 접근하므로, 실제로 사용하려면 몇 가지 설정을 선택하여야 할 것 같다.


우선 테스트를 위해서 한 번 실행해봄.


출   처 - http://igerry.com/desktop/apple-os/enabling-ftp-server-os-x-mavericks.html

사용법 - https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/launchctl.1.html


+ Recent posts