1월 15일 첫 커밋을 시작으로, 2월 12일 오후 1시 40분에 1차 편집 완성본을 만들었다. 


올해 첫 뻘짓 작업을 기획, 시행, 그리고 완성. iOS 9 Day By Day 한국어


iOS 9 Day By Day 시리즈가 PDF로 출간되었다는 소식을 접하고 번역을 할 생각을 하였다. 원본이 PDF 기준으로 책 표지까지 109페이지 밖에 안되어서 혼자 해도 얼마 안 걸릴 것 같았지만, 혼자 하면 귀찮기도 해서 빨리 번역을 해보고 색다르게 번역을 해보자는 결심해  #이상한모임 맴버를 주축으로 트위터, 페이스북에 있는 iOS 개발자들에게 낚시 글을 돌렸다. 함께 번역을 해보자고. 


총 13챕터. 한 챕터에 한 명씩 번역하기로 하였다. 커뮤니케이션 오류로 1명이 2개의 챕터를 번역을 해서 약간 꼬이기는 했지만, 무사히 번역을 마쳤다. 한 챕터당 6~10페이지 이내로, 그것도 대부분 코드와 사진이 있는지라 번역에 들어간 시간은 많지 않았다.


그리고 원저자에게 메일을 남겼다. 한국에서 놀고 먹는 iOS 개발자인 척하는 사람인데 번역을 해도 되느냐고... 기존에 Ray Wenderlich에서도 번역 활동을 한 경험도 있고 어쩌고저쩌고...


그리고 얼마 시간이 지나지 않고 답변이 왔다. 

Hi Sungwook,

Thanks for getting in touch. We're happy for you to translate iOS 9 Day By Day. If you translated the book, we would host it on our site, and then you can share the link to the wider Koren Community.

We will also add that you translated the book to the front-cover.

In a wider sense, we're also trialing a number of language specific web pages to describe to non-English speakers, exactly what we do. Is there a large number of developers in Korea who don't speak English?

Thank you for your email. It has been very interesting and I hope to speak again soon,

All the best, Matthew


이후에도 몇 번의 이메일이 오고 갔다. 초등학교 수준의 영작문 실력으로 보내도 찰떡같이 알아먹는 원어민!


구글 닥스 스프레드 시트에 간단하게 할 일 및 리스팅을 작성하고 작업을 시작했다.  그리고 또한  Github에 리포지토리를 하나 만들고 작업을 시작했다.


1월 말까지 번역을 마치고 싶어서 일주일이 지난 시점에서 한 번 빨리해달라고 쪼았...


그 이후에 문서 템플릿 통일 작업, 말투 통일 작업 등등을 하는데도 시간이 엄청나게 걸렸다. 전문적으로 해본 경험이 없다 보니 더더욱 시간이 걸리는 듯 하다. 그래서 세부적인 내용을 검토 하지 못 했다.


설 연휴까지 마치기로 마음 먹었고, 오늘까지 휴가여서 오늘 아침 부터 스타벅스에 출근해서 1차 편집 작업을 마쳤다. 휴. 


도움을 주신 13명에게 감사의 말을 남기며… 다음 뻘짓을 찾아야겠다.  


부산대학교 맞춤법 검사기, Github, MacDown, Xcode, Pages에게도 감사의 말을 전한다. 땡스 잡스.



저작자 표시 비영리
신고
Posted by KraZYeom
TAG iOS 9

난이도: 하

@available(iOS 5.0, *)
public var multipleSelectionBackgroundView: UIView?

public var selected: Bool // set selected state (title, image, background). default is NO. animated is NO

다중 선택과 체크마크가 필요해서 간단하게 구현하는 방법을 공유하겠다. 오래전에는 이것도 구현을 했었어야 했던 기억이 있는데 엄청 간단하게 바뀌었다.


우선 다중 선택이 가능하게 하기 위해서는 아래 처럼 코드 상으로 다중 선택을 활성화 하거나,

self.tableView!.multipleTouchEnabled = true

스토리보드의 TableView에서 select 부분을 Multiple Selection을 선택을 한다.


그리고 아래 코드처럼 간단하게 구현을 하면 된다.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
  // 1.
  cell.accessoryType = cell.selected ? .Checkmark : .None
  return cell
}

// 2.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
  if let cell = tableView.cellForRowAtIndexPath(indexPath) {
    cell.accessoryType = .Checkmark
  }
}

// 3.
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
  if let cell = tableView.cellForRowAtIndexPath(indexPath) {
    cell.accessoryType = .None
  }
}
  1. 현재 셀(cell)이 선택 되어 있으냐 아니냐에 따라서 체크 마크를 표시한다.
  2. 선택(select) 되었을 때는 체크 마크로 변경 한다.
  3. 선택 해제(Deselect) 되었을 때는 체크 마크를 제거 한다.




저작자 표시 비영리
신고
Posted by KraZYeom


난이도: 하


오랜만에 iOS 코딩을 하려니 많은게 바뀌었다. 


UIAlertView는 9.0에서 아래와 같이 deprecated 되었고, UIAlertController를 사용하는 것을 권장한다.

@available(iOS, introduced=2.0, deprecated=9.0, message="UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead")


그리고 UIActionSheet도 UIAlertController를 사용하면 된다. 참고로 UIActionSheet는 아래와 같이 iOS 8.3에서 deprecated 되었다.

@available(iOS, introduced=2.0, deprecated=8.3, message="UIActionSheet is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleActionSheet instead")


사용법

let alertController = UIAlertController(title: "Test Title", message: "Test Message", preferredStyle: UIAlertControllerStyle.Alert)
// .Alert .ActionSheet

let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (UIAlertAction) -> Void in
  print("Okay")
}
alertController.addAction(okAction)

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (UIAlertAction) -> Void in
  print("cancel")
}
alertController.addAction(cancelAction)

let destructiveAction = UIAlertAction(title: "Destructive", style: UIAlertActionStyle.Destructive) { (UIAlertAction) -> Void in
  print("Destructive")

}
alertController.addAction(destructiveAction)

self.presentViewController(alertController, animated: true) { () -> Void in
  print("presentViewController")
}

Alert과 ActionSheet의 구분은 preferredStyle로 구분을 해주면 되고 나머지는 동일하다. 



Alert과 ActionSheet 공통으로 주의해야 할 점은 .Default와 .Destructive는 여러 개를 .addAction해서 추가 해도 되는데, .Cancel은 2개 이상 만들어서 self.presentViewController 하면 crash 된다.


UIAlertController를 만들고, 각각의 UIAlertAction을 추가해주면 된다. 워낙 간단하니 다른 설명은 하지 않도록 하겠다.



저작자 표시 비영리
신고
Posted by KraZYeom
TAG iOS 9


iPhone 6s가 출시되면서 iOS 9에는 3D Touch와 관련된 기능이 많이 추가 되었다. 그중 하나가 Home Screen Quick Actions 기능이다. 퀵 액션, 단축 버튼과 같은 기능을 한다. 홈 스크린에서 아이콘을 꾹! 힘있게 누르면 퀵 엑션을 지원하는 앱은 바로 가기 리스트가 나타나고 없는 앱들은 탭틱 진동이 살짝 일어난다. 6s 미만의 아이폰에서는 지원하지 않는다.


앱에 3D Touch 관련 기능을 추가할 때 가장 쉬운것이 퀵 액션이다. 코드 몇 줄만 작성을 하면 기존에 앱에 코드 구조를 바꿀 필요가 없이 퀵 액션을 추가할 수 있다.


퀵 액션은 코드 상에서는 Shortcut Item이라고 부른다. 숏컷 아이템은 크게 두 가지로 나뉜다. 

  1. Static Shortcut Item
  2. Dynamic Shortcut Item

스태틱 숏컷 아이템은 plist에서 설정을 하고 변경할 수 없다. 하지만 앱에 정의 되어 있기 때문에 최소한 한번을 실행하지 않고 설치만 했을 때에도 퀵 액션을 만들 수 있다.


반면에 다이나믹 숏컷 아이템은 앱이 실행되고나서 UIApplication.sharedApplication().shortcutItems에 할당 하기 때문에 최소한 한 번 은 실행을 해줘야 다음에 나타나게 된다. 앱을 업데이트 하거나 재설치 할 때도 마찬가질수 도 있다. 하지만 고정되지 않고 원하는대로 아이템을 변경할 수 있다. 


애플의 기본앱인 사진기 앱과 전화 앱을 비교해 보면 그 차이를 알 수 있다. 사진기 앱은 기능이 딱 4개로 정해져 있다. 하지만 전화 앱은 Favorites에 설정한 상단 4명을 보여줄 수 있다. 퀵 액션에 보여주고 싶으면 리스트의 순서를 바꾸면 된다. 


원래 하고 싶었던 것은 앱을 실행 하지 않고 퀵 액션만 부르면 랜덤값으로 계속해서 변경을 해서 보여주고 싶었다. 하지만 그 방법은 없는 것으로 보인다. 최소한 한 번 이상의 앱이 실행되어야 계속 해서 랜덤값으로 할당 해 줄수 있다.


가장 간단하게 Dynamic ShortItem을 만드는 방법을 알아보도록 하자. 


앱상 어디에서 구현해도 상관은 없지만 최소한 한 번은 호출 되어야 보이기 때문에 func application(application:, didFinishLaunchingWithOptions:) 에 구현을 하면 되긴한다. 하지만 앱이 첫 번째로 실행 되었을 때만 호출이 되고 그 다음에는 호출 되지 않으므로 지속적인 변경을 위해서는 applicationDidBecomeActive(application:)에 넣으면 다음에 앱이 열였을 때도 이 메소드가 호출이 되어서 다시 숏컷 아이템을 재 할당할 수 있다.


UIApplicationShortcutItem을 만들고, UIApplication.sharedApplication().shortcutItems 에 넣으면 끝이다. 정말 간단하지 않는가? 


글로벌 변수로 스트링 값을 가진 배열을 하나 만들었다.

var randString : [String] = ["김밥", "라면", "만두", "김치찌개", "로브스터", "냉면", "비냉", "떡볶이"]


그리고 앱이 실행되면 ShortItem에 할당할 아이템을 아래와 같이 구현한다.

func applicationDidBecomeActive(application: UIApplication) {
  // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  print("applicationDidBecomeActive")

  let count = UInt32(randString.count);
  
  // 1.
  let item1 = UIApplicationShortcutItem.init(type: "type1", localizedTitle: randString[Int(arc4random_uniform(count))], localizedSubtitle: "test", icon: UIApplicationShortcutIcon(type: UIApplicationShortcutIconType.Compose), userInfo: nil)
  
  let item2 = UIApplicationShortcutItem.init(type: "type2", localizedTitle: randString[Int(arc4random_uniform(count))], localizedSubtitle: "test", icon: UIApplicationShortcutIcon(type: UIApplicationShortcutIconType.Compose), userInfo: nil)
  
  let item3 = UIApplicationShortcutItem.init(type: "type3", localizedTitle: randString[Int(arc4random_uniform(count))], localizedSubtitle: "test", icon: UIApplicationShortcutIcon(type: UIApplicationShortcutIconType.Compose), userInfo: nil)
  
  let item4 = UIApplicationShortcutItem.init(type: "type4", localizedTitle: randString[Int(arc4random_uniform(count))], localizedSubtitle: "test", icon: UIApplicationShortcutIcon(type: UIApplicationShortcutIconType.Compose), userInfo: nil)
  
  let shortcutItems : Array = [item1, item2, item3, item4]
  
  // 2.
  UIApplication.sharedApplication().shortcutItems = shortcutItems

}
  1. shortcutItems에 넣을 UIApplicationShortcutItem을 하나 만든다. type은 퀵 액션으로 호출 되었을 때 구분을 위한 것이다. localizedTitle은 텍스트로 들어갈 값이고 localizedSubtitle은 밑에 추가 설명글이다. 옵셔널이다. icon은 시스템에 내장된 아이콘을 사용해도 되고, 아니면 커스텀 아이콘을 사용해도 된다. userInfo에는 추가적으로 들어갈 정보이다. 옵셔널이다.

  2. 최대 4개의 퀵 액션을 지원하므로 4개의 아이템을 배열에 넣고 shortcutItems에 할당한다.

이렇게 하고 빌드&런을 하면 아이콘을 꾹 누르면 퀵 액션이 보여진다. 그리고 실행했다가 다시 누르면 아이템들이 변경되는 것을 확인 할 수 있다. 


하지만 숏컷을 눌러서 이제 그 type에 맞는 액션을 호출 하게 하려면 AppDelegate에서 func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)를 구현해줘야 한다. 


func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
  
  switch shortcutItem.type {
  case "type1":
    print("type1")

  case "type2":
    print("type2")
  
  case "type3":
    print("type3")
  
  case "type4":
    print("type4")
    
  default:
    print("test")
  }
}

앞에 UIApplicationShortcutItem.init에서 type으로 설정한 것이 shortcutItem.type이다. 이것으로 구분하여 각각에 퀵 액션에 대한 것을 구현 할 수 있다.


리스트 순서와 아이콘의 위치는 3D Touch Human Interface Guide Line을 참조하도록 하자.


홈 화면에서 아이콘이 상하좌우 위치에 따라서 퀵 액션(ShortCut)의 순서(order)와 아이콘의 위치가 다르게 나온다. 아이콘에서 가까운쪽이 순위가 높은거고, 아이콘의 위치는 아이콘에 가까운곳에 숏컷 아이콘이 오게 된다.


이상 아주 간단하게 퀵 액션 만드는 방법을 살펴 보았다.




저작자 표시 비영리
신고
Posted by KraZYeom

App Transport Security Problem on iOS 9

Meteor를 iOS 앱으로 실행하기 위해서 meteor run ios 또는 meteor run ios-device로 실행했더니 제대로 동작이 안된다. 살펴보니 iOS 9부터는 App과 Web간에 통신은 기본적으로 https가 문제다. 많은 앱들이 iOS 9으로 올라가면 제대로 동작 안 할 가능성이 있다.

OTL

App Transport Security support aka apps on iOS 9 don't work

xcode 7.0beta could not connect to development server.

가장 좋은 선택은 https간 통신을 하는 것이고 임시 방편으로는 꼼수가 있다. 

App-Info.plist 파일에서 아래와 같이 NSAppTransportSecurity 부분을 추가해주면 된다. 

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

추가하고 나서는 Meteor의 iOS이 잘 동작한다.

저작자 표시 비영리
신고
Posted by KraZYeom
TAG ats, iOS 9