iOS는 안드로이드와 달리 자동 SMS 전송은 불가능하고  수신받을 번호와 메세지 내용은 미리 작성하여 문자 앱 호출이 가능하다.


recipents에 전화번호를 쓰고 message에 메세지 내용을 쓰면 된다.

- (IBAction)sendSms:(id)sender {
    
    if(![MFMessageComposeViewController canSendText]) {
        UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"이 기기는 SMS 발송을 지원하지 않습니다." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [warningAlert show];
        return;
    }
    
    NSArray *recipents = @[@"010-1234-5678"];
    NSString *message = [NSString stringWithFormat:@"SMS 발송 테스트"];
    
    MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
    messageController.messageComposeDelegate = self;
    [messageController setRecipients:recipents];
    [messageController setBody:message];
    
    // Present message view controller on screen
    [self presentViewController:messageController animated:YES completion:nil];
}



iOS 10과 더불어 업데이트 된 Xcode 8.x 버전으로 기존 앱을 빌드 했을 때,

기존에 tableView Header를 커스텀 뷰로 개발하였을 때 section header view가 보이지 않는 문제가 생긴다.


해당 문제는 기존에는 디폴트 높이를 설정하지 않아도 알아서 높이가 들어 갔는데 이번 버전부터는 해당 기능이 삭제가 된듯(....)

앞으로 점점 스토리보드 위주로 갈 것이라고 생각했는데  이번 건은 오히려 스토리보드의 역할이 줄어든 듯한 느낌.. 다른 이유가 있겠지.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 30;
}

위 코드를 추가 하여 높이를 지정해주면 다시 section header view가 나타난다!

이 사실을 알기 전까지는 커스텀 헤더 뷰 지원이 중단 된 줄 알았음 ㅠ_ㅠ


아래는 대략적인 헤더 뷰 생성 예제 코드

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UIView *customTitleView = [ [UIView alloc] initWithFrame:CGRectMake(10, 0, 300, 44)];
    UILabel *titleLabel = [ [UILabel alloc] initWithFrame:CGRectMake(20, 0, 300, 44)];
    
    if(section == 0)
    {
        titleLabel.text = @"섹션1";
        titleLabel.textColor = UIColorFromHEX(0x008080);
        
    }
    else if(section == 1)
    {
        titleLabel.text = @"섹션2";
        titleLabel.textColor = UIColorFromHEX(0xFFCC66);
        
    }
    else
    {
        titleLabel.text = @"섹션3";
        titleLabel.textColor = UIColorFromHEX(0x1E90FF);
    }
     titleLabel.font = [UIFont fontWithName:@"NanumBarunGothic" size:16];
    titleLabel.backgroundColor = [UIColor clearColor];
    [customTitleView addSubview:titleLabel];
    
     return customTitleView;
}


TableView 를 사용하다 보면, 어떤 셀을 선택했느냐에 따라서 다음 화면에서의 동작이나 표시되는 컨텐츠가 다를 수 있다.


먼저, Destination ViewController의 헤더파일에서 데이터를 받을 프로퍼티를 선언

@property (strong, nonatomic) NSString *receiveID;


스토리보드에서 Segue 연결을 셀에다 다음화면을 직접 연결하는게 아니라 뷰 컨트롤러에서 다음 뷰 컨트롤러를 연결한 후 Segue ID를 설정 해 준다

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    transData = [self.datalist objectAtIndex:indexPath.row]; // Cell의 index에 따라서 datalist 배열의 해당하는 index의 데이터를 transData 변수에 저장
    [self performSegueWithIdentifier:@"DataTestSegue" sender:self];  // DataTestSegue : 스토리보드에서 연결 후 설정 한 Segue ID
}


이 후에 화면전환 시 호출되는 prepareForSegue 메소드에서 데이터 넘기기

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    
    if ([[segue identifier] isEqualToString:@"DataTestSegue"]) {    // Segue ID에 따라서 구분. 한 화면에서 여러 뷰 컨트롤러로 나뉠 때 분기별로 나눠주면 됨
        SafeZoneDetailViewController *destination = [segue destinationViewController];
        destination.receiveID = transData;
        NSLog(@"ID: %@",transData);
    }
    else if ([[segue identifier] isEqualToString:@"newDataSegue"]) {
        NewSafezoneViewController *destination = [segue destinationViewController];
        
        destination.childID = receiveID;
        NSLog(@"child ID: %@",receiveID);
    }
}


타이머 선언

타이머 ID를 여러 개 선언해서 동시에 여러 개의 타이머를 돌리는 것도 가능하다.

NSTimer *timer;
NSString *str = @"Timer";
timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self
                                           selector:@selector(updateMethod:) userInfo:str repeats:YES];


콜백 함수

- (void) updateMethod:(NSTimer *)incomingTimer
{
    NSLog(@"Inside update method");
    if ([incomingTimer userInfo] != nil)
        NSLog(@"userInfo: %@", [incomingTimer userInfo]);
}


아래와 같이 다중 타이머 선언 시 selector를 이용하여 각 타이머 별로 다중 작업이 가능하다

    NSTimer *locktimer;
    NSTimer *policytimer;
    NSString *lockstr = @"DeviceLock Timer";
    NSString *policystr = @"Policy Timer";
    
    locktimer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self
                                           selector:@selector(updateDeviceLockInfo:) userInfo:lockstr repeats:YES];
    
    policytimer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self
                                           selector:@selector(updatePolicyInfo:) userInfo:policystr repeats:YES];
- (void) updatePolicyInfo:(NSTimer *)incomingTimer
{
    NSLog(@"Inside updatePolicyInfo method");
    if ([incomingTimer userInfo] != nil)
        NSLog(@"userInfo: %@", [incomingTimer userInfo]);
}
- (void) updateDeviceLockInfo:(NSTimer *)incomingTimer
{
    NSLog(@"Inside updateDeviceLockInfo method");
    if ([incomingTimer userInfo] != nil)
        NSLog(@"userInfo: %@", [incomingTimer userInfo]);
}


앱을 개발하다 보면 구현하고자 하는 기능에 따라서 위치정보를 이용해야 할 때가 있는데

iOS에서 위치정보를 사용하려고 하면 사용자의 동의를 먼저 받아야 한다.


먼저 프로젝트에 CoreLocation Framework를 추가한다.




이후에 해당 뷰 컨트롤러에서 위치정보 사용 동의를 받는 코드를 추가한다.

.h 헤더 파일
#import <CoreLocation/CoreLocation.h>

@interface ViewController : UIViewController @property (strong, nonatomic) CLLocationManager *locationManager;
.m 구현 파일
if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
}
self.locationManager.pausesLocationUpdatesAutomatically = NO;


그리고 info.plist의 Custom iOS Target Properties에서 다음과 같이 설정해 준다.


위치정보 사용은 [사용 안함/앱을 사용할 때만/항상]  이렇게 3가지 형태가 있는데 필요한 기능에 따라서

requestAlwaysAuthorization 이나 requestWhenInUseAuthorization을 써주면 된다.

만약 항상 위치정보를 사용하지 않아도 되는데 requestAlwaysAuthorization을 사용한다면 심사 과정에서 리젝이 날 수도있으니 주의한다.

(경험 상 리뷰어한테도 충분히 설명을 해 줘야함)






'프로그래밍 > iOS - OBJC' 카테고리의 다른 글

iOS NSTimer 호출하기  (1) 2016.05.12
맥 OS X PhoneGap 설치  (0) 2016.04.27
iOS 8에서 푸시 알림 동의 받기  (0) 2016.03.10
Singleton 패턴 사용하기  (0) 2016.03.09
iOS 앱 자동로그인  (0) 2016.03.09

iOS 7->8 로 넘어오면서 푸시알림 동의 받는 코드가 바뀌었다.

개발 중인 앱은 최소 iOS 버전이 iOS 8버전 이상이지만 혹시나 구버전을 지원해야 하는 경우도 있기 때문에 함께 기록 해 본다.


  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        NSLog(@"Requesting permission for push notifications...iOS 8"); // iOS 8
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:
                                                UIUserNotificationTypeAlert | UIUserNotificationTypeBadge |
                                                UIUserNotificationTypeSound categories:nil];
        [UIApplication.sharedApplication registerUserNotificationSettings:settings];
    } else {
        NSLog(@"Registering device for push notifications...iOS 7 and earlier"); // iOS 7 and earlier
        [UIApplication.sharedApplication registerForRemoteNotificationTypes:
         UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
         UIRemoteNotificationTypeSound];
    }
}


그리고 아래는 디바이스가 APN 서버에 정상적으로 등록 되었는지 로그를 찍어서 확인 할 수 있는 코드

- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)settings
{
    NSLog(@"Registering device for push notifications...iOS 8"); // iOS 8
    [application registerForRemoteNotifications];
}

- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token
{
    NSLog(@"Registration successful, bundle identifier: %@, mode: %@, device token: %@",
          [NSBundle.mainBundle bundleIdentifier], [self modeString], token);
}

- (void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"Failed to register: %@", error);
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)notification completionHandler:(void(^)())completionHandler
{
    NSLog(@"Received push notification: %@, identifier: %@", notification, identifier); // iOS 8
    completionHandler();
}

- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)notification
{
    NSLog(@"Received push notification: %@", notification); // iOS 7 and earlier
}

- (NSString *)modeString
{
#if DEBUG
    return @"Development (sandbox)";
#else
    return @"Production";
#endif
}



'프로그래밍 > iOS - OBJC' 카테고리의 다른 글

iOS NSTimer 호출하기  (1) 2016.05.12
맥 OS X PhoneGap 설치  (0) 2016.04.27
iOS에서 위치정보 사용 동의 받기  (0) 2016.03.10
Singleton 패턴 사용하기  (0) 2016.03.09
iOS 앱 자동로그인  (0) 2016.03.09

+ Recent posts