iOS – 음성 바꾸기

원문

필독
… 생략

iOS 기능 중 텍스트를 음성으로 내주는 기능있습니다. 정말 강력한 기능이고, 또한 남자 또는 여자 목소리 또한 선택이 가능합니다.

아래에 보시면 언어에 따른 각 다른 목소리를 골라 사용할 수 있습니다.

[AVSpeechSynthesisVoice 0x17e30940] Language: ar-SA, Name: Maged, Quality: Default, 
[AVSpeechSynthesisVoice 0x17d3e150] Language: cs-CZ, Name: Zuzana, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e79700] Language: da-DK, Name: Sara, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e50c50] Language: de-DE, Name: Anna, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ec30f0] Language: el-GR, Name: Melina, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e687f0] Language: en-AU, Name: Karen, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e23be0] Language: en-GB, Name: Daniel, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e6ffc0] Language: en-IE, Name: Moira, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ec79b0] Language: en-US, Name: Samantha (Enhanced), Quality: Enhanced, 
[AVSpeechSynthesisVoice 0x17e795a0] Language: en-US, Name: Samantha, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e75900] Language: en-ZA, Name: Tessa, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e27ec0] Language: es-ES, Name: Monica, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ec5e10] Language: es-MX, Name: Paulina, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e799c0] Language: fi-FI, Name: Satu, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ec61c0] Language: fr-CA, Name: Amelie, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e75b10] Language: fr-FR, Name: Thomas, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ee2460] Language: he-IL, Name: Carmit, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ef5140] Language: hi-IN, Name: Lekha, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e6f840] Language: hu-HU, Name: Mariska, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e59bd0] Language: id-ID, Name: Damayanti, Quality: Default, 
[AVSpeechSynthesisVoice 0x17d2c950] Language: it-IT, Name: Alice, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ebaec0] Language: ja-JP, Name: Kyoko, Quality: Default, 
[AVSpeechSynthesisVoice 0x17d42100] Language: ko-KR, Name: Yuna, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ee3130] Language: nl-BE, Name: Ellen, Quality: Default, 
[AVSpeechSynthesisVoice 0x17d637d0] Language: nl-NL, Name: Xander, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e7c8b0] Language: no-NO, Name: Nora, Quality: Default, 
[AVSpeechSynthesisVoice 0x17d3e430] Language: pl-PL, Name: Zosia, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e33190] Language: pt-BR, Name: Luciana, Quality: Default, 
[AVSpeechSynthesisVoice 0x17eabf00] Language: pt-PT, Name: Joana, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e2a650] Language: ro-RO, Name: Ioana, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e232b0] Language: ru-RU, Name: Milena, Quality: Default, 
[AVSpeechSynthesisVoice 0x17ee6830] Language: sk-SK, Name: Laura, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e64a10] Language: sv-SE, Name: Alva, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e62fc0] Language: th-TH, Name: Kanya, Quality: Default, 
[AVSpeechSynthesisVoice 0x17df4080] Language: tr-TR, Name: Yelda, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e76a10] Language: zh-CN, Name: Ting-Ting (Enhanced), Quality: Enhanced, 
[AVSpeechSynthesisVoice 0x17db4850] Language: zh-CN, Name: Ting-Ting, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e2ecf0] Language: zh-HK, Name: Sin-Ji, Quality: Default, 
[AVSpeechSynthesisVoice 0x17e224c0] Language: zh-TW, Name: Mei-Jia, Quality: Default]

위 코드에 맞는 언어/나라

Arabic (Saudi Arabia) - ar-SA
Chinese (China) - zh-CN
Chinese (Hong Kong SAR China) - zh-HK
Chinese (Taiwan) - zh-TW
Czech (Czech Republic) - cs-CZ
Danish (Denmark) - da-DK
Dutch (Belgium) - nl-BE
Dutch (Netherlands) - nl-NL
English (Australia) - en-AU
English (Ireland) - en-IE
English (South Africa) - en-ZA
English (United Kingdom) - en-GB
English (United States) - en-US
Finnish (Finland) - fi-FI
French (Canada) - fr-CA
French (France) - fr-FR
German (Germany) - de-DE
Greek (Greece) - el-GR
Hindi (India) - hi-IN
Hungarian (Hungary) - hu-HU
Indonesian (Indonesia) - id-ID
Italian (Italy) - it-IT
Japanese (Japan) - ja-JP
Korean (South Korea) - ko-KR
Norwegian (Norway) - no-NO
Polish (Poland) - pl-PL
Portuguese (Brazil) - pt-BR
Portuguese (Portugal) - pt-PT
Romanian (Romania) - ro-RO
Russian (Russia) - ru-RU
Slovak (Slovakia) - sk-SK
Spanish (Mexico) - es-MX
Spanish (Spain) - es-ES
Swedish (Sweden) - sv-SE
Thai (Thailand) - th-TH
Turkish (Turkey) - tr-TR

실제로 사용 하는 방법을 알아보겠습니다.

let voice = AVSpeechSynthesisVoice(identifier: AVSpeechSynthesisVoiceIdentifierAlex)

다른 목소리를 사용하기 위해서, 이름으로 매칭하여 사용 할 수 있습니다. [code]identifier[/code]으로는 매치가 안됩니다.

목록 불러오기

var voiceToUse: AVSpeechSynthesisVoice?
for voice in AVSpeechSynthesisVoice.speechVoices() {
    if #available(iOS 9.0, *) {
        if voice.name == "Karen" {
        voiceToUse = voice
        }
    } 
} 

텍스트를 주어 음성을 내는 방법은 아래와 같습니다.

let utterance = AVSpeechUtterance(string: "Hello from iOS.")
utterance.voice = voiceToUse
let synth = AVSpeechSynthesizer()
synth.speakUtterance(utterance)

iOS – 유닛 테스트 쉽게 하기! (Swift 2 + XCode 7)

원문

유닛 테스트를 하기 위해 아래의 항목을 확인해주어야 한다.

1. 내부 클래스 만들기

만약 새롭게 내부 클래스를 만들었다면, 클래스나 메서드를 찾지 못한다면, 아래와 같이 Public 처리를 해주어야 한다.

NewImage

2. Import with @testable

테스트 타겟에서, 아래와 같이 @testable keyword를 사용하여, 모듈을 import해줘야한다.

NewImage

3. Test하기

모든게 완료되었다. 외부 클래스나 메서드도 쉽게 테스트 할 수 있다.

NewImage

끝.

iOS 9 – 새로운 UIAlertController, Swift Closures and Enumeration

원본 자료

iOS 8 SDK가 나오면서, 그렇게 큰 관심을 두가지 변화 점에 대해서 설명하고자 한다.
이전에는 UIActionSheetUIAlertView가 사용되었다면, 이제는 UIAlertController라는 클래스를 대체 사용하여야 한다.

iOS 8에서, 앱 내 Alert 메시지를 표현하고 싶다면, 위에서 언급한 UIAlertSheetUIAlertView가 아닌 UIAlertController를 사용하여야 한다. UIAlertController내 Enum값으로 두가지 스타일을 제공한다. 스타일 설정으로 우리는 UIAlertSheetUIAlertView를 선택 할 수 있다. 그냥 둘중에 하나만 선택하며 되는것이다. 또한 우리가 액션을 등록할 때 ex)UIAlertViewDelegate를 사용하였다면, 이제는 closures나, Objective-C에서의 블럭 코드를 사용해야 한다.


이 소개 페이지에서는 UIAlertConroller 클래스 사용법과 alert message표현 방법과 action sheet에 대해서 설명할 것이다.

NewImage

자 시작해보자.

새로운 Xcode 프로젝트 생성

데모하기에는 새로운 프로젝트를 생성하는 방법이 가장 좋다. 자 Single View Application 템플릿을 선택하고, UIAlertDemo라는 이름으로 프로젝트를 생성해보자.

!! Swift Language 선택하는 것을 잊지 말도록!.

여기서는 Xcode 6 Beta를 사용했다는 것을 염두해 두길 바란다. (번역자 데모 실행 7버전도 정상적으로 동작함)

Xcode 6에서는 기본적으로 Size Classes가 활성화 된다.
!! Size Classes기능은 모든 화면을 자동으로 수용하는 기능이다.

여기서는 간단하게 Size Classes 기능을 비활성화 하는 것으로 한다. Main.storyboard에 File inspector옵션에서 “Use Size Classes”기능을 체크를 해지하자. 체크를 해지하게 되면 Device Type선택 창이 보여질 것이고. 우리는 iPhone을 선택 할 것이다.

화면은 아래와 같이 볼 수 있을 것이며, 간단한 버튼 컴퍼넌트를 드래그 하여 넣어주자. 제목은 간단하게 “Hello Alert”로 넣어주자.

NewImage

Action 메서드 추가하기

ViewController.swift에 아래와 같이 코드를 작성해주자.이는 나중에 “Hello World” 버튼을 클릭했을 때 취해지는 액션 메서드이다. 추후 스토리보드에서 버튼과 저 메서드를 따로 연결 시켜주어야 한다.

@IBAction func showAlert() {

}

알다시피, OutletAction은 스토리보드에서 소스코드와 UI Object를 연결하게 해준다.

Swift에서는 메서드 앞에 @IBAction 붙여주면 된다.

자 그러면 이제 실제로 메서드와 UI Object를 연결해보자.

Document Outline에서, CTRL을 누르고, View Controller에을 클릭 후 “Hello Alert”까지 드래그 해주자 그리고 “showAlert”를 선택해주자.

아래의 그림과 같이 될 것이다.

NewImage

실제 Alert를 표현하기 위해 UIAlertViewController를 사용하기

거의 모든 설정이 완료되었다. 이번에는 간단하게 alert message를 표현하는 가장 기본이 되는 것을 설명할 것이다. 간단하게 표현하기 위해 기초가 되는 것은 아래와 같다.

  • UIAlertController 객체 생성! (title, message, alert controller의 스타일 선택)

  • UIAlertAction 생성과 위에서 생성한 alert controller에 반인딩!

  • 마지막으로, presentViewController 메서드를 호출함으로써 alert controller 을 보여주기!

우리는 swift를 사용하고, 위 룰에 충족 시킨다면 코드는 아래와 같이 나올 것이다.


@IBAction func showAlert() {
        let alertController = UIAlertController(title: "Hey AppCoda", message: "What do you want to do?", preferredStyle: .Alert)
        
        let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
        alertController.addAction(defaultAction)
        
        presentViewController(alertController, animated: true, completion: nil)
}

간단하죠? alert나 action sheet를 표현하는 방법은 위와 동일합니다. 단지 스타일만 선택해주면 된다. .Alert를 선택한다면, alert message를 보여주고, .ActionSheet 스타일을 지정한다면, action sheet가 표현될것이다.

기본적으로, alert controller는 아무 액션도 포함하고 있지 않다. 만약, 어떠한 액션을 추가하고 싶다면, 예로 alert의 버튼 액션이 취해졌을때 사라지게 하고 싶다면, 우리는 UIAlertAction 객체를 생성하고 addAction메서드를 활용하여, alert controller에 연결시켜주어야 한다.

UIAlertAction을 생성할때 두가지 파라미터를 받는다. 제목과 핸들러이다. 핸드로는 블럭 코드로, 버튼이 눌려졌을 때 실행되는 부분이며, handler에 nil을 포함하게 되면, controller는 사라지는 기능만 가지게 될것이다. 이부분에 대해서 나중에 더 이야기 하도록 하겠다.

마지막으로, presentViewController메서드를 호출함으로써 alert controller 를 표현할 것이다. 만약 앱을 실행하고, 버튼을 클릭하게 되면 아래와 같이 실행될 것이다.

NewImage

Swift에서 Enumeration에 대한 설명

Swift코드 작성이 처음이라면, .Alert와 .ActionSheet이 생소할 것이다. 그 부분같은 경우 아래와 같이 full syntax로 사용할 수 있다.

let alertController = UIAlertController(title: "Hey AppCoda", message: "What do you want to do?", preferredStyle: UIAlertControllerStyle.Alert)

위 코드는 우리가 사용했던 부분과 완전히 동일한 방법이고, 사실 UIAlertControllerStyle은 아래와 같이 enumration이다.

enum UIAlertControllerStyle : Int { 
     case ActionSheet 
     case Alert 
}

swift에서 enumeration은 값들을 다 그룹화 시킬때 사용된다. AlertSheet와 Alert는 enumeration 안에 멤버 값으로 정의된다. objective C와 같지 않게 만들때 상수는 아니다. AcitonShee와 Alert는 0 그리고 1로 정의되지는 않는다. 각 각 멤버들은 enumberation에서의 full-fledged 값을 가진다.

쉽게 말하면, 딱 정해진 값은 아니지만, 그 안에서는 독립된 값을 가지게 된다.

UIAlertControllerStyle.Alert로 사용할 수 도 있지만 .Alert를 사용하도록 하자.

당신의 짧은 코드는 당신이 더 쉽게 읽을 수 있도록 한다.

Action Handler와 Closures

UIAlertController로 돌아가보자. 우리가 이야기 아직 이야기 하지 않은 것중 하나, UIAlertAciton의 handler이다. 우리가 UIAlertAction 객체를 생성할때 우리는 handler에 블럭 코드를 작성하기 되는데, 이 블럭 코드는 사용자로부터 이벤트를 받았을 때 실행되는 코드이다.

showAlert 메서드 안에 아래와 같이 코드를 작성하고 다른 액션을 취하도록 해보자.

let callActionHandler = { (action:UIAlertAction!) -> Void in
            let alertMessage = UIAlertController(title: "Service Unavailable", message: "Sorry, the call feature is not available yet. Please retry later.", preferredStyle: .Alert)
            alertMessage.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
            self.presentViewController(alertMessage, animated: true, completion: nil)
        }
        let callAction = UIAlertAction(title: "Call", style: .Default, handler: callActionHandler)
        alertController.addAction(callAction)

우리는 새로운 handler를 정의하고 이를 추가하였다. 위 코드는 간단하게 alert 버튼이 눌려졌을 때 취하는 액션을 정의하고 추가만 해줬을 뿐이다. 블럭코드는 Closure로 알려져 있다.

Closures는 코드 자체를 기능으로 할 수 있는 블럭을 자체적으로 포함하고 있다. 이것은 위와 같이 Objective-C에 블럭과 굉장히 흡사하다.

action closure에 값 같은 것을 제공하기 위한 한가지 방법은 코드 블럭과 같은 상수 또는 변수이다.

코드 블럭의 첫 번째 부분은 UIAlert Action의 handler 파라미터들과 리턴 타입를 정의하는 것이고, in 키워드는 이후로는 closure의 몸체 부분이 시작되는 부분이다.

NewImage

위 처럼 closure를 각 변수나 상수로 정의하는 것은 필수가 아니다. 아래와 같이 간단하게 closure을 파라미터처럼 활용 할 수도 있다. 아래와 같이 간단하게 사용 할 수 있다.

let callAction = UIAlertAction(title: "Call", style: .Default, handler: {
            action in
                let alertMessage = UIAlertController(title: "Service Unavailable", message: "Sorry, the call feature is not available yet. Please retry later.", preferredStyle: .Alert)
                alertMessage.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
                self.presentViewController(alertMessage, animated: true, completion: nil)
                }
        )
alertController.addAction(callAction)

결론

UIAlertController는 clsures의 사용 (또는 Objective-C의 블럭)을 포용하고 있으며, 이로써 우리는 UIAlertController을 잘 활용 할 수 있을 것이라고 예상한다.

iOS/OSX – validate phone number

I need to check whether i can use the phone number or not in iOS/OSX.
This is what i found solution at the stack over flow.

NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex];
BOOL phoneValidates = [phoneTest evaluateWithObject:phoneNumber];
NSString *phoneRegex = @"^((\\+)|(00))[0-9]{6,14}$";

thanks.

iOS > Test API about getting text size.

It’s new API to get the size of text for iOS7.

NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:14]};
CGSize titleSize = [str sizeWithAttributes:attributes];
NSLog(@"New API > string width->%f, height->%f",titleSize.width, titleSize.height);

It’s deprecated API to get the size of text on iOS7.

titleSize = [str sizeWithFont:[UIFont systemFontOfSize:14]];
NSLog(@"Old API > string width->%f, height->%f",titleSize.width, titleSize.height);
# New API > string width->70.322000, height->16.702000
# Old API > string width->71.000000, height->17.000000

The new api is correct more then the old api. but the new api is only able to use on iOS7. if you support the under version of iOS 7. you should use the old one.

iOS – UITextField Text 정렬하기

제대로 된 코더가 되자. – 오래된 코드는 사용하지 말아라.


기말고사 시험도 끝나고 한달전부터 배포되고 있는 Account+를 iOS7에 맞추어 개선시키고 있습니다.

물론 하위 버전과 호환은 안되구요. 이전버전은 물론 Account+를 사용하면 되기 때문입니다.

하지만 이번에는 iPhone/iPad/OS X/Window/Chrome용을 개발할려고 합니다.

(엄청나게 프로젝트가 밀려있는 상황)

잡설은 이제 그만 타이틀과 같이 iOS7 UITextField에서 Text 수직 정렬이 속성은 Center로 들어가 있지만 약간은 내려가 있어 TextField의 좌표를 수정할려고 했지만 의존된 컴퍼넌트가 많아 속성을 찾아봤습니다.

간단하게 아래와 같이 존재하더라구요.

textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

위 방법 말고도 실제로 정렬 할 수 있는 방법은 여러가지가 있습니다.

입맛에 맞게 할 수 있는게 개발에 매력이 아닐까요?

XCode > 시간을 절약하는 5가지 방법 – Snippet(1)

iPhone 애플리케이션을 개발한지 어언 5년? 오랜 시간이 지났지만 정말 단축키를 사용하지 않았던거 같습니다. 부분적으로 아주 조금만 사용했읍죠.

예를 들어 Cmd+1, Cmd+2 정도…

영어 공부를 목적으로 캐나다를 한 일년 정도 다녀오고 (물론 개발도 꾸준히 했죠.) Clojure1라는 언어에 잠깐 미쳐지냈던 지라 생각보다 iPhone에는 많은 시간을 투자 하지 못했었습니다.

회사에서 따분한 시간들을 보내면서 잠깐 동안 과거에 어떻게 시간을 보냈는지, 어떻게 하면 시간을 절약하고 어떻게 하면 시간을 유용하게 사용할 수 있을 지를 생각하고 또 생각했습니다.

제가 사실 Clojure라는 언어에 시간을 보냈던 이유는 함수형 언어라는 특징과 정말 코드가 간단하고 미래에 많은 사람들이 그리고 기존에 있던 언어들이 함수형 언어와 비슷해지거나 아니면 함수형 언어를 사용되지 않을까 해서였습니다.

물론 지금도 생각은 바뀌지 않았습니다.

서술이 너무 길었던 거 같습니다.
아래의 내용은 NSCookbook이라는 사이트 중 하나의 포스트를 발 번역/개작한겁니다.


시간이 흐르고 작업을 하다보면 때로는 좌절하고는 합니다. 저처럼… 이유인 즉슨 소비하지 않아도 될 시간을 낭비해서이죠. 개발자에겐 시간이 금이라고 생각됩니다.

하지만!! 개발자에게 있어 툴이란 정말 중요하죠. XCode는 시간을 절약할 수 있는 방대한 기능을 제공합니다. 그래서 용량도 참 크죠.

이 포스터에서는 XCode의 새로은 특징과 이전에 있었던 기능들을 되새겨 보는 시간을 가지도록 하겠습니다.

1.Snippets

XCode Snippets을 사용하면 단편적인 설명과 자동완성의 기능을 사용할 수 있습니다.

XCode가 발전했음에도 불구하고 Snippets은 이전의 것과 같습니다. 그래서 이번에 새롭게 생성하고 사용하는 방법을 배워보도록 하겠습니다.

기존에 만들어져있는 메서드의 경우 모든 개발자가 동일시 하게 사용하는 표준문안으로 작성되었습니다.

구현부인 .m파일에서 init을 입력 후 enter를 입력해보시면 아래와 같이 생성된 것을 확인 할 수 있습니다.

참조 1
참조 2

XCode에서는 위와 같이 자동완성을 제공하는 Snippets기능이 있습니다.
View > Utilizes > Show Code Snippets Library 또는 control+option+cmd+2 단축키를 누르면 오른쪽 하단에 창하나가 보여지는 것을 확인 할 수 있습니다.

typedef’s, coreData helpers, GCD helpers 등 여러가지를 보실 수 있습니다.

자 이제 새로운 하나 dispatch_after라는 코드블럭을 추가해보도록 합시다.

생성 방법은 구현부에서 마음에 드는 블럭을 코드 Snippets Libarary 창으로 드래그 & 드롭 해주시면 됩니다.

Sample Code
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//code to be executed on the main queue after delay
});

또는 **dispatch_once 코드 블럭을 넣어봅시다.

Sample Code 2
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//code to be executed once
});

코드를 넣게 되면 맨 하단에 Snippet이 생성된 것을 확인 할 수 있습니다.
새로 생성된 Snippet을 클릭해주시면 아래와 같은 필드들을 보실 수 있습니다.

  • Title pragma mark같은 의미있는 이름을 적으세요.
  • Summary 작은 설명 부분입니다. 필수 내용은 아니니 Skip할 수있습니다.
  • Platform iOS 또는 OS X 아니면 둘다를 지원할 지 선택 할 수 있습니다.
  • Language 언어 선택 부분입니다. 저희는 Objective-C를 사용하죠.
  • Completion Shortcut 이 부분은 정말 중요한 부분입니다. 자동완성 키워드인입니다. 예를 들어 mark라고 지정을 했다고 가정하고 m을 입력 할 시 자동완성 팝업을 제공하는 것을 확인 할 수있습니다.
  • Completion Scope 어느 부분에서 제공을 할 지 선택하는 부분입니다. 예를 들어 선언부에서만 보이고 싶다면 선언부 또는 구현부를 선택해주시면 됩니다.

이제 다 되었으니 Done을 누르고 다음에 입력한 키워드를 입력해주세요.
코드 완성이 된 것을 확인하셨나요?

이게 정말 시간을 절약할 수 있는 혜택 아닐까요? 이제 좀 더 유용한 자기만의 snippets을 만들어보세요.

참조 3

여기서 한가지 팁 더! paragma mark snippet을 입력하지 않은 상태에서 위와 같이 버블 창이 떠서 이름을 입력받을 수 있다면 더 좋지 않을까요?

이건 좀더 어려운 부분이 될수도 있지만 정말 필요한 부분이기도 합니다.
자 입력 받을 수 있도록 추가해보도록 하죠.

  • Snippets Library에서 추가한 Snippet을 열고 Edit를 눌러주세요.
  • 버블창안에 입력창을 만들기 위해서는 XCode Snippeit Library가 인식할 수 있는 키워드가 필요합니다. 그건 꺽쇠'<#’,’#>’로 구현되어 있으며 아래와 같을 수 있습니다.
    <#input text#>
  • pragma mark snippet을 위해 저희는 아래와 같이 <#name#>을 문장 끝에 추가하도록 하겠습니다.

참조 4

이게 전부입니다. 아래는 다른 Snippets가 되겠습니다. 잘 이용하면 더욱 더 시간을 절약할 수 있습니다.

로그 메서드 (logm)
NSLog(@”%@ – %@”, NSStringFromClass([self class]), NSStringFromSelector(_cmd))
지역화 메서드 (loc)
NSLocalizedString(@”<#string#>”, @”<#message#>”)

저는 또한 다른 코드 블럭들을 넣어놨습니다. 예를 들어 CGRect를 위한 logr, float를 위한 logf같은 것들을 말이죠.

다음 포스트에서는 Method Auto-completion에 대해서 발번역을 해보도록 하겠습니다.

수고하셨습니다.


  1. Rich Hickey라는 사람이 만들었으며, 이 언어는 기존 Lisp라는 언어에 영향을 받은 언어로써 기존 자바라이브러리를 사용 할 수있고 JVM 위에서 동작한다. 

iPhone > Detecting user inactivity/idle time since last screen touch

ref

- (void)sendEvent:(UIEvent *)event {
    [super sendEvent:event];

    // Only want to reset the timer on a Began touch or an Ended touch, to reduce the number of timer resets.
    NSSet *allTouches = [event allTouches];
    if ([allTouches count] > 0) {
        // allTouches count only ever seems to be 1, so anyObject works here.
        UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
        if (phase == UITouchPhaseBegan || phase == UITouchPhaseEnded)
            [self resetIdleTimer];
    }
}

- (void)resetIdleTimer {
    if (idleTimer) {
        [idleTimer invalidate];
        [idleTimer release];
    }

    idleTimer = [[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO] retain];
}

- (void)idleTimerExceeded {
    NSLog(@"idle time exceeded");
}

where maxIdleTime and idleTimer are instance variables.

In order for this to work, you also need to modify your main.m to tell UIApplicationMain to use your delegate class (in this example, AppDelegate) as the principal class:

int retVal = UIApplicationMain(argc, argv, @"AppDelegate", @"AppDelegate");