반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

TestFlight Beta Testing

2015. 9. 24. 08:50 | Posted by 솔웅


반응형

TestFlight Beta Testing


TestFlight Beta Testing 은 iOS 앱을 앱스토어에 release 하기 전에 사용자들에게 미리 테스트 해 볼 수 있도록 한다.
애플 ID 로 이메일을 보내는 방식으로 테스트 할 유저를 1000명까지 초대할 수 있다.







TestFlight 준비하기
Xcode 와 iTunes Connect 를 사용해서 빌드하고 셋업하기
테스터들에게 앱을 테스트하도록 하기 위해 XCode 에서 앱의 beta build 를 업로드 하고 iTunes Connect 에 테스터들의 이름과 이메일 주소를 업로드 한다.
beta app 과 테스터들의 리스트를 셋업하는 방법은 iTunes Connect Developer Guide 에 나와 있고 TestFlight video tutorial에도 설명 돼 있다.




   
TestFlight Beta Tester들 초청하기 


Internal Testers


iTunes Connect 에서 Technical이나 Admin role을 수행하고 있는 팀원 25명에게 beta build를 배포해서 feedback을 받는다.
각 팀원별로 10개의 device를 테스트용으로 사용할 수 있다.

External Testers


준비가 되면 beta tester로 팀원이 아닌 1000명의 사용자를 초청할 수 있다.
외부테스터에게 제공하는 앱은 Beta App Review를 필요로 하고 테스팅하기 전에 전체  App Store Review Guidelines 을 참고하고 이를 준수해야 한다.
Review를 통해서 새로운 버전에서 문제점들을 해결한 보다 완결된 기능을 제공할 수 있다.
한번에 10개의 앱들이 한번에 테스트 될 수 있다. (Internally or Externally)


TestFlight App for iOS


Download on the App Store


테스터를 초대할 때마다, 테스터들은 beta tester 그룹에 join 하라는 초대메일을 받게 된다.  그리고 앱스토어에서 TestFlight 앱을 인스톨 하도록 안내 받게 된다.
TestFlight 앱은 beta app을 인스톨 할 수 있게 해 준다. UDID나 Provisioning Profiles 등을 track 하지 않아도 된다.


View the TestFlight App



Updates


beta app 이 인스톨 되면 TestFlight 은 새로운 build 가 생성될 때마다 테스터들에게 공지하게 된다. 그리고 어떤 부분에 포커스를 둘지 등을 제공받고 쉽게 feedback을 줄 수 있도록 한다.





Using TestFlight as a Beta Testers

Installing


테스터는 device 10개 까지 TestFlight 을 설치해서 사용 가능하고 여러가지 앱을 여러 개발자를 위해서 테스트 할 수 있다. 동시에 테스트 할 수 있는 앱의 갯수는 제한이 없다. TestFlight 은 iOS 8 이상의 버전이 깔려있는 iPhone, iPad 그리고 iPad touch 에서 iOS 앱을 테스트 하는데 사용할 수 있다. Mac 앱은 테스트 할 수 없다. 만약 beta app 이 테스터의 device 에 load 되지 않는다면 개발자에게 문의 한다.

Testing

invitation을 accept 하면 테스트를 위해 invite 된 앱의 beta version을 다운 받을 수 있다. 만약 live 버전이 있다면 beta 앱은 그 live version을 replace 할 것이다. beta 앱을 다운 받으면 앱 이름 옆에 오렌지색 점을 볼 수 있을 것이다. 이것은 beta 버전임을 알리기 위해 표시한 것이다. TestFlight 은 새로운 build 가 available 하면 notice를 보낼 것이다. 그리고 어느 부분에 Focus를 맞출지에 대한 정보를 제공할 것이다. TestFlight의 App Details 페이지에 있는 Provide Feedback 버튼을 클릭하면 쉽게 feedback을 보낼 수 있다. 이 이메일은 자동적으로 적절한 앱과 device detail등을 포함하게 되고 테스트는 추가사항과 screenshot 등을 덧붙이면 된다.

beta 테스트는 30일 동안 유효하고 시작은 테스터들에게 이 beta version 이 release 된 날이다. TestFlight 안에는 각 앱의 Open 버튼 안에 남은 일자가 표시돼 있다.

만약 beta App 에 In-App Purchase 기능이 포함되 있으면 그것을 구매하지 말아야 한다. 이 beta 버전에서는 금액이 결제되지 않을 것이다.

Opting Out (수신 거부)

email invitation 을 accept 하지 않으면 이 beta app은 설치되지 않을 것이다. 그리고 당신은 tester 리스트에 포함되지 않을 것이다. 또한 email 의 밑에 있는 링크를 눌러서 unsubscribe를 할 수 있다. 만약 그 invitation을 accept 했는데 더 이상 테스트 하고 싶지 않다면 TestFlight의 App Details 페이지에서 delete 할 수 있다.



반응형


반응형


공부하는 Introducing iOS8 의 Chapter 9 에 나오는 Selfie App 입니다.


우선 Main.storyboard를 이용해서 아래와 같은 화면을 만드세요.




가운데는 Image View 이고 왼쪽 오른쪽은 Bar Button Item 입니다.


import UIKit
import Social

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {


  @IBOutlet weak var myImageView: UIImageView!
 

  @IBAction func selfieTapped(sender: AnyObject) {
    var imagePicker = UIImagePickerController()
    imagePicker.delegate = self
   
    if UIImagePickerController.isSourceTypeAvailable(.Camera){
      imagePicker.sourceType = .Camera
     
      if(UIImagePickerController.isCameraDeviceAvailable(.Front)) {
        imagePicker.cameraDevice = .Front
      } else {
        imagePicker.cameraDevice = .Rear
      }
    } else {
      imagePicker.sourceType = .PhotoLibrary
    }
   
    self.presentViewController(imagePicker, animated: true, completion: nil)
  }
 
  func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [NSObject : AnyObject]?) {
    myImageView.image = image
    self.dismissViewControllerAnimated(true, completion: nil)
  }
 
  @IBAction func shareTapped(sender: AnyObject) {
    var social = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
    social.addImage(myImageView.image)
   
    self.presentViewController(social, animated: true, completion: nil)
  }
}


우선 Facebook에 접속할 거니까 Social 을 import 합니다.

그리고 클래스 선언하는데에 UIImagePickerControllerDelegate, UINavigationControllerDelegate 를 추가합니다.


그리고 Take Selfie 와 Share button 들에 대한 함수를 만듭니다. Connection을 Outlet 이 아닌 Action으로 선택하면 됩니다.

각각 selfieTapped 와 shareTapped 라는 함수를 만듭니다.


그리고 가운데 사진이 들어갈 Image View에 대한 객체도 만들구요. 

여기서는 함수 이름을 imagePicker로 했습니다.



일단 selfieTapped 함수를 보면 UIImagePickerController() 에 대한 객체를 만들어서 delegate를 현재의 view로 설정합니다. (self)


그리고 if 문을 사용해서 Camera가 가능한지 여부를 체크하구요.

가능하면 또 다시 전면이 가능한지 체크를 합니다. 전면 카메라가 가능하지 않으면 후면 카메라를 지정하고 가능하면 전면 카메라를 지정합니다.


그리고 만약에 카메라 자체가 가능하지 않으면 전면 후면 확인할 필요 없이 그냥 Photo Library 를 지정합니다.


마지막 줄은 image Picker를 화면 전체에 표시하는데 밑에서부터 위로 올라오도록 설정한 겁니다.


그러면 Take Selfie 버튼을 눌렀을 때 카메라를 찍을 수 있는 화면이 나오는 설정을 한 겁니다. (카메라 기능이 없으면 Photo Library 가 나오구요.)


다음은 didFinishPickingImage delegate method 를 추가 합니다.


이 메소드는 사전에 Swift에 정의된 메소드 입니다. 이 메소드는 사용자가 사진을 찍었거나 Photo Library에서 사진을 선택 했을 때 호출 됩니다.

두번째 image 파라미터에 사진이 전달되게 되는 겁니다.


함수 내용을 보면 첫번째 줄에서 파라미터로 전달받은 image를 myImageView 의 image로 받습니다.

이렇게 받은 다음에 imagePicker가 없어지도록 합니다.


이러면 사진을 찍고 그 사진을 imagePicker에 받는 것까지 마친겁니다.


이제 이 사진을 맘대로 다룰 수가 있는데요.

이 앱에서는 Facebook으로 보낼 겁니다.


이 기능은 사용자가 Share 버튼을 누를 경우 일어나게 됩니다.

그러니까 shareTapped 함수 안에 코딩을 해야 되겠죠.


일단 서비스 타입을 Facebook으로 한 SLComposeViewController를 만듭니다. 그 변수 이름은 social 이구요.

그리고 그 controller 에 아까 받았던 이미지를 추가합니다.


마지막 줄은 SLComposeViewController 가 표시되도록 한 겁니다.






여기까지 진행이 되면 위와 같은 화면이 나오는데요.

이건 제 컴의 에뮬레이터로 실행한 겁니다. Facebook 이 setting 돼 있지 않아서 직접 Post 는 안되는데 아마 Setting을 하면 Posting 까지 될 겁니다.


반응형

[Swift] Social Network Service (Facebook, Twitter)

2015. 9. 19. 22:39 | Posted by 솔웅


반응형

Apple Document

https://developer.apple.com/library/prerelease/ios/documentation/NetworkingInternet/Reference/SLComposeViewController_Class/index.html

+ the Book (Introducing iOS 8 Swift programming from Idea to App Store by Steve Derico)


SLComposeViewController

SLComposeViewController 클래스는 SNS 를 지원하기 위한 view를 제공한다.
isAvailableForServiceType: 메소드는 트위터 같은 SNS 가 셋업 돼 있는지 view를 제공하기 전에 미리 체크하는 역할을 한다.

글을 올리는 것과 관련된 모든 메소드들은 boolean 값을 반환한다. 그 content 가 알맞지 않거나 view controller가 이미 사용자게게 그 내용을 present 한 경우에는 No를 반환한다. view controller에 제공하기 전에 반드시 그 content를 set 해야 한다. 사용자는 view controller 에 그 content가 제공된 이후에야 편집을 할 수 있다.

completionHandler property를 사용해서 handler를 사용해 사용자가 포스팅을 완료 했을 때 통보 받을 수 있다. 





project details 에서 Social.framework를 add 하고 view Controller 에서 import Social 을 해서 이 프레임워크를 import 한다.

SLComposeViewController는 생성될 때 반드시 serviceType 이 제공돼야 한다.
serviceType 프로퍼티는 다음과 같은 두개의 옵션이 있다.

SLServiceType Facebook
SLServiceTypeTwitter

어떤 서비스 타입이 사용 가능한지 체크하려면 isAvailableForServiceType 메소드를 사용한다.
if(SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook)){}

아래와 같이 forServiceType 메소드를 사용해서 SLComposeViewController 를 생성할 수 있다.

if(SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook)){
    var myComposeViewController = SLComposeViewController
    (for ServiceType: SLServiceTypeFacebook)
}

initial text를 세팅하려면 setInitialText 메소드를 사용한다.

var myComposeViewController = SLComposeViewController
(forServiceType: SLServiceTypeFacebook)

myComposeViewController.setInitialText("I love this app")

이미지를 추가하려면 addImage 메소드를 사용한다.

myComposeViewController.addImage(myImage)

메세지에 URL을 추가하려면 addURL 메소드를 사용한다.
이 메소드는 NSURL을 파라미터로 받는다. 이 NSURL은 string 이랑 아주 유사하다.

var myURL = NSURL(string: "http://www.google.com")
myComposeViewController.addURL(myURL)

이제 생성된 SLComposeViewController를 view Controller에 세팅을 하려면 ViewController(_:animated: completion:) 메소드를 사용한다.

self.presentViewController(myComposeViewController, animated: true, completion: nil)






Creating a Social Compose View Controller


반응형


반응형

요즘 도서관에서 이 책을 빌려서 Swift를 공부하고 있거든요.


Chapter 9 Camera, Photos, and Social Networks 를 공부하기 전에 애플의 document 를 미리 공부해 봤습니다. (UIImagePickerController)


중간에 이 책 9장에 있는 내용들도 좀 첨가 했어요.


https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImagePickerController_Class/


UIImagePicker Controller


해당 기기에서 제공하는 사진이나 비디오 촬영에 대한 기능을 다루는 클래스
그 외에 저장된 이미지나 비디오를 사용해 앱에서 활용할 수 있도록 해 줌
이 콘트롤러는 이 결과를 delegate object 에게 전달하게 된다.

초기화는 아래와 같이 한다.
var imagePicker = UIImagePickerController()

UIImagePickerControllerSourceTypeCamera: 사진이나 비디오를 찍을 때 사용해
UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeSavedPhotosAlbum: 저장된 사진이나 비디오를 활용할 때 사용해

사용 방법
1. isSourceTypeAvailable를 사용해서 사용 가능 여부를 판별한다. UIImagePickerControllerSourceType enumeration 로부터 constant가 제공된다.


if UIImagePikcerController.isSourceTypeAvailable(.Camera) {
// 카메라 사용 가능 하면 소스타입을 세팅한다.
imagePicker.sourceType = .Camera
} else {
// 카메라 사용 불가능
}

기기에 따라 전면/후면 카메라가 있을 수 도 있는데 이럴 땐 이렇게 사용한다.

if UIImagePikcerController.isCameraDeviceAvailable(.Front) {
// 전면 카메라 사용 가능
} else {
// 전면 카메라 사용 불가능
}

if UIImagePikcerController.isCameraDeviceAvailable(.Rear) {
// 후면 카메라 사용 가능
} else {
// 후면 카메라 사용 불가능
}

사용 가능한 카메라가 없으면 UIImagePickerController는 사용자에게 Photo Library에서 사진이나 비디오를 고를 수 있도록 해 줄 수 있다.
imagePicker.sourceType = .PhotoLibrary

2. availableMediaTypesForSourceType 를 사용해서 가능한 소스타입을 체크한다. 사진과 비디오에 대한 사용을 구분해 준다.


3. mediaTypes property 를 세팅함으로서 image picker controller 에게 해당 미디어 타입(사진, 비디오)에 해당되는 UI를 조정해 준다.

모바일 타입을 바꾸려면 Mobile Core Services 프레임워크를 import 해야 한다.
이 프레임워크에는 다음과 같은 키워드가 있다.
kUTTypeImage : Photos and images
kUTTypeMovie : Movies and videos

mediaTypes 프로퍼티를 배열에 넣고 사용한다.
imagePicker.mediaTypes = [kUTTypeImage]
imagePicker.mediaTypes = [kUTTypeMovie]

4. 현재 활성화 된 View의 presentViewController:animated:completion:를 호출 함으로서 iPhone, iPod touch 등에 맞는 UI를 제공한다.
   새로운 view controller 로 현재 configure 된 image picker controller 를 passing 하게 된다.
   iPad 에서는 소스타입에 따라 image picker를 제공하는 방법이 다른데 아래를 참고 하면 된다.
   Camera               | Photo Library              | Saved Photos Album
   Use full screen     | Must use a popover     | Must use a popover

  
소스 타입이 UIImagePickerControllerSourceTypePhotoLibraryUIImagePickerControllerSourceTypeSavedPhotosAlbum이면 popover controller 를 사용해서 image picker를 제공해야 한다. full screen으로 제공하려고 하면 exception이 일어날 것이다.

Presenting and Dismissing the Popover.

UIImagePickerControllerSourceTypeCamera소스타입을 사용하면 이 image picer를 full-sccreen 이나 popover 아무거나 사용할 수 있다. 애플에서는 full-screen을 사용할 것을 추천하고 있다.

5. 새로 찍거나 저장돼 있는 사진이나 비디오를 선택하기 위해 사용자가 버튼을 누르거나 해당 작업을 cancel 하면 delegate object를 사용한 image picker 가 dismiss 하게 된다. 새로 찍힌 미디어는 delegate 가 이것을 기기의 카메라 롤에 저장할 수 있다. 이전에 저장된 미디어인 경우 delegate는 원하는 대로 이용 될 수 있다. 보다 자세한 사항은 Taking Pictures and Movies. 를 참조.

image picker controller를 customize 할 수 있다. 이렇게 하려면 overlay view를 사용한다. 이 overlay view 는 display 하려는 것을 콘트롤 하고   Capturing Still Images or Movies 에 있는 메소드들 을 사용하게 된다.

cameraOverlayView

custom overlay view를 display 할 수도 있다.
UIImagePickerController 클래스에 대한 Custom overlay view는 iOS 3.1 이상에서 가능하다. cameraOverlayView property 를 사용하면 된다.
Using UIImagePickerController to Select Pictures and Take Photos 에 그 예제가 있다.

Important
UIImagePickerController 는 portrait 모드만 지원한다. 이 클래스는 subclassing을 지원하지 않는다. view hierarchy 는 private 이고 modified 될 수 없다. 예외가 있다면 custom view를 cameraOverlayView 프로퍼티에 assign 할 수 있다. 그렇게 하면 추가적인 정보를 제공할 수 있고 카메라 인터페이스와 여러분의 코드 사이의 상호작용을 관리할 수 있다.




Delegate Object 제공하기

image picker controller를 사용하려면 UIImagePickerControllerDelegate protocol에서 허용된 delegate를 제공해야 한다. iOS 4.1 부터는 이미지와 함께 카메라 롤에 사진의 metadata 도 저장할 수 있게 됐다.
See UIImagePickerControllerDelegate Protocol Reference


UIImagePickerController에 미디어에서의 이벤트들을 전달하기 위해서는 delegate를 사용하는데 현재 뷰 콘트롤러에서 작업하는 경우는 self를 사용한다.
imagePicker.delegate = self
물론 클래스를 만들 때 이 delegate를 넣어야 한다.
class ViewController: UIViewController, UIImagePickerControllerDelegate {
}

UIImagePickerController는 UINavigationController를 상속했기 때문에 그 delegate도 UINavigationControllerDelegate 프로토콜을 상속하고 있다.
이 프로토콜은 push나 pops 같은 UINavigationController 이벤트의 update들을 전달한다. 이것을 사용하려면 이렇게 한다.
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
}

사진이 찍히거나 앨범에서 사진이 선택 됐을 때 UIImagePickerControllerDelegate는 아래 메소드를 호출한다.
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {}

사용자가 사진이나 비디오를 생성하거나 선택했을 때는 아래 메소드를 호출한다.
func imagePickerController(picker:UIImagePickerController, didFinishPickingMediaWithInfo: [NSObject : AnyObject]) {}

Flash Mode 조정하기

iOS 4.0 부터 사용자가 flash 모드, 전면/후면 카메라 사용 그리고 사진과 비디오 촬영을 선택할 수 있도록 하는 custom control을 제공할 수 있다. 그리고 프로그램으로 이 기능들을 컨트롤 할 수도 있다. 그리고 flash 의 strobe light 같은 것들도 콘트롤 할 수 있다.
cameraFlashMode property 를 UIImagePickerControllerCameraFlashModeOn UIImagePickerControllerCameraFlashModeOff에 세팅함으로서 flash LED를 켜거나 끌 수 있다.

Working with Movies


비디오 촬영시간의 디폴트 는 10 분이지만 videoMaximumDuration property를 사용해서 조정할 수 있다.
사용자가 share 버튼을 눌러서 MMS, MobileMe, YouTube, or another destination으로 비디오를 보낼 때 적당한 duration limit 과 적당한 video 퀄리티가 enforce 된다.

디폴트 카메라 인터페이스는 이전에 저장된 비디오를 editing 할 수 있도록 지원한다. Editing 은 비디오의 첫부분이나 끝 부분부터 일정 부분을 잘라내서 그 부분을 저장하는 기능이다. 이 인터페이스를 표시하려면 UIVideoEditorController 클래스를 사용한다.
See UIVideoEditorController Class Reference.

allowsEditing 프로퍼티를 true로 놓는다.
imagePicker.allowsEditing = true로
이렇게 하면 편집 스크린이 추가될 것이다.

Fully-Customized Media Capture and Browsing

fully-customized image/비디오 캡쳐를 실행하려면  Media Capture and Access to Camera에서 설명하고 있는 AV Foundation framework을 사용한다. 이 AV Foundation framework을 이용해서 카메라를 사용하는 것은 iOS 4.0 이후부터 가능해 졌다.

photo library를 살펴보기 위해 fully-customized image picker를 생성하려면 Photos framework에 있는 클래스들을 사용한다. 예를 들어 더 큰 thumbnail 이미지를 표시하는 custom image picker를 생성할 때 timestamp 와 위치정보를 포함한 이미지의 메타데이터를 사용하거나  MapKit 과 iCloud Photo sharing등과 같은 기능하고 같이 사용하도록 할 수 있다. 좀 더 자세한 사항은 Photos Framework Reference를 보면 된다. Photos framework을 이용한 Media browsing은 iOS 8.0 이상부터 가능하다.



Setting the Picker Source


반응형

[Swift] 현재 위치 맵에 표시하기

2015. 9. 14. 09:28 | Posted by 솔웅


반응형

지난 글에 스위프트로 현재 위치 정보를 얻어서 다루는 방법에 대해 공부했습니다.

이번엔 현재 위치를 가지고 맵에 표시하는 방법을 공부해 보겠습니다.


오늘도 VEA Software의 강좌를 가지고 공부했습니다.


https://www.veasoftware.com/tutorials/2015/7/25/map-view-current-location-in-swift-xcode-7-ios-9-tutorial


이것은 xcode 7 으로 작업했더라구요. 그래서 소스를 받아서 6.4 에서 돌리니까 에러가 났습니다.

그래서 7.1 beta를 설치해서 거기서 돌리니까 제대로 돌아가더라구요.


그런데 이전에 작업했던 걸 불러오니까 자기가 Convert 시켰는데도 실행이 안되네요.

애플의 개발 툴도 아주 안정적이지는 않은 것 같아요.



하여간 일단 소스코드를 보겠습니다.


import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate
{
    @IBOutlet weak var mapView: MKMapView!
   
    let locationManager = CLLocationManager()
   
    override func viewDidLoad()
    {
        super.viewDidLoad()
       
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
       
        self.mapView.showsUserLocation = true
       
    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Location Delegate Methods
   
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
    {
        let location = locations.last
       
        let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
       
        self.mapView.setRegion(region, animated: true)
       
        self.locationManager.stopUpdatingLocation()
    }
   
    func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
    {
        print("Error: " + error.localizedDescription, terminator: "")
    }
   
}


CoreLocation과 관련된 것은 이전 글에서 다뤘으니까 여기서 따로 다루지는 않겠고...


맵을 사용하려면 우선 MapKit 을 import 하고 CLLocationManagerDelegate를 클래스에 추가합니다.


그리고 화면에 맵을 표시해야 하니까 Main.storyBoard 를 사용해서 MapView를 스크린에 얹고 변수 mapView 를 선언합니다.


다음에 viewDidLoad 메소드에 CLLocationManager()를 사용해 구현한 4개의 라인 밑에 맵뷰의 showsUserLocation을 true로 세팅합니다.


이러면 사용자 위치를 보여줄 수 있도록 사전 준비가 다 된 겁니다.


다음은 CLLocationManagerDelegate의 didUpdateLocations 메소드를 구현합니다.

이 메소드 안을 보면 우선 가장 최근의 위치정보를 location 에 담구요 


Core Location의 Data Type 중 하나인 CLLocationCoordinate2D를 사용합니다.

이 데이터 타입에는 CLLocationAccuracy, CLLocationDegrees, CLLocationDirection, CLLocationDistance 그리고 CLLocationSpeed 등이 있습니다.


CLLocationCoordinate2D는 위도와 경도 정보를 받는 겁니다.

이 위도 경도 정보를 center라는 변수에 담습니다.



다음은 MKCoordinateRegion 을 사용합니다. 이것은 MapKit의 데이터 타입중 하나입니다.

이외에 MKCoordinateSpan, MKMapPoint, MKMapSize, MKMapRect, MKZoomScale 등이 있습니다.


MKCoordinateRegion은 위도 경도에 해당하는 지역을 맵의 중앙에 위치하고 MKCoordinateSpan 은 지도의 scale을 정할 수 있습니다.


이렇게 region을 완료하면 그 다음에 이 region을 mapView 에 세팅을 하면 됩니다.

이때 animated는 true로 선언하구요.


그리고 나서 locationManager의 stopUpdatingLocation()을 호출해서 업데이트를 중지시킵니다.


이렇게 하면 지도에 현재의 위치를 표시하게 됩니다.





반응형

[Swift] 현재 위치 정보 다루기

2015. 9. 14. 00:02 | Posted by 솔웅


반응형

요즘 Swift를 이용해서 iOS 모바일 어플리케이션 개발을 공부하고 있습니다.


스위프트로 현재 위치를 파악하려면 CoreLocation 을 사용해야 합니다.

아래 강좌를 한번 따라 해 봤는데요.


https://www.veasoftware.com/tutorials/2015/5/12/current-location-in-swift-xcode-63-ios-83-tutorial


일단 비쥬얼한 부분은 없이 코드만 있는 샘플입니다.

ViewController.swift 부분만 분석해 보겠습니다.


import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate
{
   
    let locationManager = CLLocationManager()
   
    override func viewDidLoad()
    {
        super.viewDidLoad()
       
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
       
    }
   
    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
   
    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
    {
       
        CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error)->Void in
           
            if (error != nil)
            {
                println("Error: " + error.localizedDescription)
                return
            }
           
            if placemarks.count > 0
            {
                let pm = placemarks[0] as! CLPlacemark
                self.displayLocationInfo(pm)
            }
            else
            {
                println("Error with the data.")
            }
        })
    }
   
    func displayLocationInfo(placemark: CLPlacemark)
    {
       
        self.locationManager.stopUpdatingLocation()
        println(placemark.locality)
        println(placemark.postalCode)
        println(placemark.administrativeArea)
        println(placemark.country)
       
    }
   
    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!)
    {
        println("Error: " + error.localizedDescription)
    }
}


우선 CoreLocation 을 import 합니다.

그리고   ViewController 에 Delegate 프로토콜을 불러옵니다.


이 ViewController라는 클래스는 UIViewController 클래스와 CLLocationManagerDelegate 프로토콜을 사용한다고 처음에 선언했는데요.

이 CLLocationManagerDelegate 프로토콜은 location과 heading updates를 CLLocationManager 로부터 받게 됩니다.

(Delegate는 제 생각에는 자바에서의 일종의 리스너 역할을 하는 것 같습니다.)

이 Delegate를 사용하는 것은 나중에 보게 되는데요. 사전에 정의된 수많은 location event들에 대해 필요한 메소드들을 불러서 구체적인 부분을 코딩해 나가시면 됩니다.

이건 나중에 보구요. 우선 순서대로 다시 보자면


CLLocationManager() 를 초기화 시킵니다. 이 클래스는 Location 과 heading 관련된 이벤트들을 전달하는 것을 configuring 하는 핵심 포인트인데요. 이 클래스의 인스턴스를 만들어서 location과 heading 이벤트를 언데 전달되고 이 이벤트들을 전달하는 일을 시작하고 끝내는 등의 역할을 하게 됩니다. 


위의 소스코드에서는 locationManager라는 이름으로 이 클래스를 초기화 시켰습니다.


그 다음은 viewDidLoad() 라는 함수를 보시면 됩니다.

이 함수는 UIViewController에 이미 정의돼 있는 함수인데요. UIViewController를 상속했기 때문에 이 함수를 Override 해서 사용할 수 있습니다.

이 함수는 해당 화면이 뜬 이후에 실행이 되게 됩니다.

그러니까 화면이 뜬 후에 제일 먼저 일어나야 할 일들을 여기에더가 정의 해 두면 됩니다.



super.viewDidLoad()로 이미 정의된 기능을 다 실행하도록 한 후에 아래 4개의 라인을 실행합니다.


        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()


일단 CLLocationManager의 delegate를 self로 선언하고 다음에 desiredAccuracy는 Best 로 합니다.

이 외에 KCLLocationAccuracyNearestTenMeters, KCLLocationAccuracyHundredMeters, KCLLocationAccuracyKilometer, KCLLocationAccuraryThreeKilometer 등이 있습니다.

필요한 걸 골라서 쓰면 됩니다. Best 인 경우는 위치정보의 정확도가 가장 좋은 겁니다. 그러면 배터리 소모량이 많아 지겠죠.


그리고 requestWhenInUseAuthorization() 은 이 Location 정보를 이용하려고 할 때 사용자로부터 승인 여부를 묻는데 사용됩니다. 위치정보를 사용할 때 반드시 사용자의 허락을 받아야만 합니다. 이것 외에 requestAlwaysAuthorization() 도 있습니다. 첫번째 것은 앱이 foreground에서 실행 될 때에만 묻고 두번째 것은 forground이든 background 이던 다 물을 수 있습니다.




그 다음은 startUpdateingLocation()를 호출함으로서 Location Service를 사용할 수 있게 됩니다.


이제 locationManager는 사용자의 위치를 tracking 하고 그 값을 전달해 줄 수 있습니다.


didReceiveMemoryWarning()은 override 한 함수로 여기서 따로 살펴 보지는 않겠습니다.


그 다음에 나오는 함수가 바로 CLLocationManagerDelegate에 미리 정의 돼 있던 여러 메소드들을 사용하는 건데요.

첫번째로 didUpdateLocations를 가져왔습니다.

이 함수는 Location이 업데이트 됐을 때 실행되는 함수입니다.


그 안의 코딩을 보면 에러를 핸들링하고 에러가 없을 경우에는 위치 정보를 displayLocationInfo 함수에 전달해 주도록 하고 있습니다.


이 displayLocationInfo는 미리 정의돼 있던 함수가 아니라 개발자가 만든 함수입니다.


이 함수에는 전달받은 위치정보 중에서 locality (도시), postalCode(우편번호)administrativeArea(주) 그리고 country (나라) 정보를 콘솔에 print 하도록 했습니다.


그리고 마지막은 다시 CLLocationManager 의 Delegate에 미리 정의돼 있던 didFailWithError 메소드를 사용했습니다.

에러가 날 경우에는 에러 정보를 print 하도록 했습니다.


이렇게 해서 모든 소스코드를 분석해 봤습니다.



이 강좌에서는 위치 정보를 사용하기 위해서 info.plist에 NSLocationWhenInUseUsageDescription을 추가하라고 돼 있습니다.

그리고 제가 공부하던 다른 책에서는 NSLocationWhenInUsageDescription, NSLocationAlwaysUsageDescription 그리고 NSLocationUsageDescription을 추가하라고 돼 있구요.


그런데 저는 이 것들을 다 추가해도 앱이 제대로 실행이 안 되더라구요.

빌드는 제대로 되는데 저 위 그림에 있는 사용자에게 위치정보 사용 승인을 받는 alert 창이 안 뜨더라구요.


무슨 다른 세팅을 해야 되는지.... ? 잘 모르겠습니다.


일단 이 강좌에 있는 소스파일들을 다운 받아서 실행해서 테스트는 해 봤습니다.

다운 받은 소스의 info.plist에는 아무것도 추가가 안 돼 있던데...


왜 제가 만든 소스코드는 제대로 실행이 안되는지 모르겠네요.


이제 Current Location 정보를 받아서 사용하는 부분은 어느정도 알 것 같습니다.


반응형
이전 1 다음