Skip to content

SDK Guide

Kwon, oh-sang edited this page Jul 11, 2013 · 26 revisions

SDK Guide

bass.io 에서는 앱 개발자들이 많이 사용하시는 사용자 관리, 파일 업/다운로드, Push 메시지 송/수신등의 기능을 손쉽게 사용할 수 있는 클라우드 기반 서비스를 제공한다.

bass.io에서 제공되는 SDK는 REST API에 익숙하지 않은 개발자 분들도 간단한 설정만으로 baas.io의 backend platform 의 모든 기능을 사용할 수 있도록 구성되어 있다..

baas.io iOS SDK는 baas.io의 REST API의 간단한 구현체이다.

SDK만으로 baas.io의 모든 feature을 사용 할 수 있도록 설계했지만, 좀 더 깊은 이해를 원하면 REST API 가이드 를 참고하면 된다.

[[TOC]]

Debug 모드 (개발용)

didFinishLaunchingWithOptions(권장) 에 아래와 같이 설정하면 디버그 모드로 동작한다.

기본은 릴리즈 모드이다. 릴리즈 시 끄는 것을 잊지 말자.

[[Baasio sharedInstance] isDebugMode:YES];

디버그 모드는 개발의 편의를 위해 만들어진 것인데, 특징은 아래와 같다.

  • API호출 형태 및 상세한 로그가 찍힌다.
  • 최신 SDK가 있다면 알려준다.

SDK에서 최신 기능이 추가되거나 버그에 대한 hotfix 등등으로 인하여 버젼이 올라갔을 경우,

디버그 모드에서는 아래와 같은 메세지를 보여준다. (눈에 보이기 쉽게 50줄이 표시 된다.)

★☆★☆ The new Baas.io SDK Release. see this link https://github.com/baasio/baas.io-sdk-ios (current : ${설치 된 버젼}, new : ${최신 버젼}) ★☆★☆"

Entity

Entity

baas.io의 Entity 객체는 기본적으로 key/value 형태의 Dictionary이다.

미리 정의된 값들은 @property 선언되어 바로 참조가 가능하지만 그 외 사용자가 원하는 값은 아래와 같은 방법으로 읽고, 쓰기가 가능하다.

	BaasioEntity *entity = [BaasioEntity entitytWithName:@"GameScore"];

	//이미 정의 된 프로퍼티에 셋팅
	entity.name = @"cetauri";
	
	//이미 정의 된 프로퍼티 읽기
	NSString *name = entity.name;
	BaasioEntity *entity = [BaasioEntity entitytWithName:@"GameScore"];

	//커스텀 프로퍼티 셋팅
	[entity setObject:[NSNumber numberWithInt:1337] forKey:@"score"];
	[entity setObject:@"Sean Plott" forKey:@"playerName"];
	[entity setObject:[NSNumber numberWithBool:NO] forKey:@"cheatMode"];

	//커스텀 프로퍼티 읽기
	NSString *score = [entity objectForKey:@"score"];
	NSString *playerName = [entity objectForKey:@"playerName"];
	NSString *cheatMode = [entity objectForKey:@"cheatMode"];
	

미리 정의된 @property는 다음과 같다.

  • uuid : 키
  • created : 작성일
  • modified : 최종수정일
  • type : entity 명

Entity 저장

데이터를 저장 후 error를 확인하여 성공 여부를 확인하여 작업하면 된다.

    BaasioEntity *entity = [BaasioEntity entitytWithName:@"SomeBlog"];
    [entity setObject:@"제목"forKey:@"title"];
    [entity setObject:@"내용" forKey:@"content"];
    [entity setObject:@"작성자" forKey:@"writer"];
    [entity save:error]
    
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }                

Entity Async

비동기 작업의 경우 Blocks를 이용하였다. 처음에는 조금 어려워 보일 수도 있지만 Delegate를 사용하는 것보다 더 편하다는 것을 알게 될 것이다.

Blocks에 대해서는 Blocks Programming Topics를 참고하기를 바라지만, 짧게 설명하면 2가지로 요약이 가능하다.

  • Method의 argument로 코드 블럭을 넘기는 것이다.
  • baas.io의 경우 ^ 바로 뒤가 리턴값 되도록 구현하였다.(^(void)는 void가, ^(BaasioEntity *entity)는 entity가 리턴된다.)

대부분의 경우 동기(Sync)와 비동기(Async) API를 동시에 제공하나, 일반적으로 대부분의 프로그래밍을 비동기(Async)로 작성된다.

    BaasioEntity *entity = [BaasioEntity entitytWithName:@"SomeBlog"];
    [entity setObject:@"제목"forKey:@"title"];
    [entity setObject:@"내용" forKey:@"content"];
    [entity setObject:@"작성자" forKey:@"writer"];
    [entity saveInBackground:^(BaasioEntity *entity) {
                    NSLog(@"success : %@", entity.description);
                }
                failureBlock:^(NSError *error) {
                    NSLog(@"fail : %@", error.localizedDescription);
                }];
    

Entity 가져오기

    [BaasioEntity getInBackground:@"SomeBlog"
                             uuid:uuid
                     successBlock:^(BaasioEntity *entity) {
                         NSLog(@"entity : %@", entity.description);
                     }
                     failureBlock:^(NSError *error) {
                         NSLog(@"fail : %@", error.localizedDescription);
                     }];

Entity 수정

    BaasioEntity *entity = [BaasioEntity entitytWithName:@"SomeBlog"];
    entity.uuid = uuid;
    [entity setObject:@"30" forKey:@"duration"];

    [entity updateInBackground:^(BaasioEntity *entity) {
                                        NSLog(@"entity : %@", entity.description);
                                    }
                                    failureBlock:^(NSError *error) {
                                        NSLog(@"fail : %@", error.localizedDescription);
                                    }];

Entity 삭제

    BaasioEntity *entity = [BaasioEntity entitytWithName:@"SomeBlog"];
    entity.uuid = uuid;
    [entity deleteInBackground:^(void) {
                                    NSLog(@"success");
                                }
                                failureBlock:^(NSError *error) {
                                    NSLog(@"fail : %@", error.localizedDescription);
                                }];

Entity Relationship

Entity간의 relation이 필요할 때가 있다.

예를 들면 블로그(blogEntity)와 댓글(commentEntity)처럼 1:N 관계를 설정한다고 한다면, Primary가 되는 Entity에 connect method를 부르고 relation 이름과 해당 Entity를 넘겨주면 된다.

Connect

    [blogEntity connectInBackground:commentEntity
                       relationship:@"blogWithComment"
                       successBlock:^(void){
                           //성공
                       }
                       failureBlock:^(NSError *error){
                           NSLog(@"fail : %@", error.localizedDescription);
                       }];

Disconnect

Connect와 같은 방법으로 하면 연결이 해제된다.

    [blogEntity disconnectInBackground:commentEntity
                          relationship:@"blogWithComment"
                          successBlock:^(void){
                              //성공
                          }
                          failureBlock:^(NSError *error){
                              NSLog(@"fail : %@", error.localizedDescription);
                          }];

User

User 기능은 users Collection을 통해 지원되며, 사용자의 회원가입, 로그인 및 정보의 관리 기능을 제공한다.

회원가입

    NSError *e = nil;
    BaasioUser *user = [BaasioUser user];
    user.username = @"cetauri";       // 다음 코드도 같다. [user setObject:@"user name" forKey:@"username"];
    [user setObject:@"password" forKey:@"password"];
    [user setObject:@"cetauri@gmail.com" forKey:@"email"];
    [user setObject:@"권오상" forKey:@"name"];
    [user setObject:@"kwon, ohsang" forKey:@"eng_name"];	 //추가된 정보
    [user setObject:@"M" forKey:@"sex"];	 				//추가된 정보
    [user signUp:&e];
    
    if(e){
        NSLog(@"fail : %@", e.localizedDescription);
    }
    BaasioUser *user = [BaasioUser user];
    user.username = @"cetauri";       // 다음 코드도 같다. [user setObject:@"user name" forKey:@"username"];
    [user setObject:@"password" forKey:@"password"];
    [user setObject:@"cetauri@gmail.com" forKey:@"email"];
    [user setObject:@"권오상" forKey:@"name"];
    [user setObject:@"kwon, ohsang" forKey:@"eng_name"];	 //추가된 정보
    [user setObject:@"M" forKey:@"sex"];	 				//추가된 정보
    
    [user signUpInBackground:^(void) {
                    NSLog(@"success");
                }
                failureBlock:^(NSError *error){
                    NSLog(@"fail : %@", error.localizedDescription);
                }];

또한 회원 가입은 static method를 이용하여 간단히 생성 가능하지만, 입력 필드는 "id, 암호, 이름, 메일"로 제한된다.

    [BaasioUser signUp:@"My ID"
            password:@"My Password"
                name:@"My name"
               email:@"email@baas.io"
               error:&error];
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }	             
    [BaasioUser signUpInBackground:@"My ID"
                          password:@"My Password"
                              name:@"My name"
                             email:@"email@baas.io"
                      successBlock:^(void) {
                          NSLog(@"success");
                      }
                      failureBlock:^(NSError *error) {
                          NSLog(@"fail : %@", error.localizedDescription);
                      }];

로그인

    [BaasioUser signIn:@"My ID" password:@"My Password" error:&error];
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    
    [BaasioUser signInBackground:@"My ID"
                        password:@"My Password"
                    successBlock:^(void) {
                        NSLog(@"success");
                    }
                    failureBlock:^(NSError *error) {
                        NSLog(@"fail : %@", error.localizedDescription);
                    }];

수정

    BaasioUser *user = [BaasioUser currentUser];
    user.username = @"cetauri";
    [user setObject:@"20" forKey:@"age"];
    [user update:&error];
    BaasioUser *user = [BaasioUser currentUser];
    user.username = @"cetauri";
    [user setObject:@"20" forKey:@"age"];
    [user updateInBackground:^(BaasioUser *user) {
                         NSLog(@"success.");
                    }
                    failureBlock:^(NSError *error) {
                         NSLog(@"error : %@", error.localizedDescription);
                    }];
    

탈퇴

    BaasioUser *user = [BaasioUser currentUser];
    [user unsubscribeInBackground:^(void) {
                        NSLog(@"success.");
                     }
                     failureBlock:^(NSError *error) {
                        NSLog(@"error : %@", error.localizedDescription);
                     }];
    BaasioUser *user = [BaasioUser currentUser];
    [BaasioUser unsubscribe error:&error];
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }

페이스북

페이스북에서 받은 token을 이용하여, 페북을 통한 회원가입 및 로그인을 할 수 있다.

회원가입

    NSString *accessToken = @"......"	//facebook Token
    [BaasioUser signInViaFacebook:accessToken error:&error];
	
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    NSString *accessToken = @"......"	//facebook Token
    [BaasioUser signInViaFacebookInBackground:accessToken
                                 successBlock:^(void){
                                    NSLog(@"success : %@", file.uuid);
                                 }
                                 failureBlock:^(NSError *error) {
                                    NSLog(@"error : %@", error.localizedDescription);
                                 }

로그인

    NSString *accessToken = @"......"	//facebook Token
    [BaasioUser signUpViaFacebook:accessToken error:&error];
	
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    NSString *accessToken = @"......"	//facebook Token
    [BaasioUser signUpViaFacebookInBackground:accessToken
                                 successBlock:^(void){
                                    NSLog(@"success : %@", file.uuid);
                                 }
                                 failureBlock:^(NSError *error) {
                                    NSLog(@"error : %@", error.localizedDescription);
                                 }

기타

로그인

일단 로그인이 되면 SDK 내부에서 baas.io 서버에서 발급해준 token을 가지고 있다.

그리고 token이 있다면 그 후부터는 모든 RESTFul API 접근 시에 자동으로 token을 실어서 보낸다.

로그인 된 사용자의 정보

    BaasioUser *user = [BaasioUser currentUser];
    if(user == nil){
        //로그인 안됨
    }else{
        //로그인 됨
        NSLog(@"user : %@", user.description);
    }

혹은 아래와 같이 사용하면 된다.

    BOOL isLogin = [[Baasio sharedInstance]hasToken]

Group

Group 기능은 Group Collection을 통해 지원되며, 그룹을 만들어 회원을 그룹 지을 수 있다.

Group 생성

vip라는 group 생성

    BaasioGroup *group = [[BaasioGroup alloc]init];    
    [group setObject:groupName forKey:@"vip"];
    [group save:&error];
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    BaasioGroup *group = [[BaasioGroup alloc]init];    
    [group setObject:groupName forKey:@"vip"];
    [group saveInBackground:^(BaasioGroup *group){
                    NSLog(@"group : %@", group.description);
                }
                 failureBlock:^(NSError *error){
                     NSLog(@"fail : %@", error.localizedDescription);
                 }];

Group 정보 수정

    BaasioGroup *group = [[BaasioGroup alloc]init];
    group.uuid = uuid;
    [group setObject:@"Kwon oh-sang" forKey:@"master"];
    [group setObject:@"special" forKey:@"nick"];
    [group update:&error];
    
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }    
    BaasioGroup *group = [[BaasioGroup alloc]init];
    group.uuid = uuid;
    [group setObject:@"Kwon oh-sang" forKey:@"master"];
    [group setObject:@"special" forKey:@"nick"];
    
    [group updateInBackground:^(BaasioGroup *group){
                    NSLog(@"group : %@", group.description);
                }
                 failureBlock:^(NSError *error){
                     NSLog(@"fail : %@", error.localizedDescription);
                 }];

Group 삭제

group의 uuid로 group 삭제

    BaasioGroup *group = [[BaasioGroup alloc]init];    
    group.uuid = uuid
    [group delete:&error];
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    BaasioGroup *group = [[BaasioGroup alloc]init];    
    group.uuid = uuid
    [group deleteInBackground:^(BaasioGroup *group){
                    NSLog(@"group : %@", group.description);
                }
                 failureBlock:^(NSError *error){
                     NSLog(@"fail : %@", error.localizedDescription);
                 }];

Group 사용자 추가

    BaasioGroup *group = [[BaasioGroup alloc]init];
    [group setUserName:@"User Name or User UUID"];
    [group setGroupName:@"Group Name"];
    
    [group add:&error];
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    BaasioGroup *group = [[BaasioGroup alloc]init];
    [group setUserName:@"User Name or User UUID"];
    [group setGroupName:@"Group Name"];
    
    [group addInBackground:^(BaasioGroup *group){
                    NSLog(@"group : %@", group.description);
                 }
                 failureBlock:^(NSError *error){
                     NSLog(@"fail : %@", error.localizedDescription);
                 }];

Group 사용자 제거

    BaasioGroup *group = [[BaasioGroup alloc]init];
    [group setUserName:@"User Name or User UUID"];
    [group setGroupName:@"Group Name"];
    
    [group remove:&error];
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    BaasioGroup *group = [[BaasioGroup alloc]init];
    [group setUserName:@"User Name or User UUID"];
    [group setGroupName:@"Group Name"];
    
    [group removeInBackground:^(BaasioGroup *group){
                    NSLog(@"group : %@", group.description);
                 }
                 failureBlock:^(NSError *error){
                     NSLog(@"fail : %@", error.localizedDescription);
                 }];

Group 사용자 조회

조회는 Query를 사용해야 한다.

자세한건 아래에서 다시 한번 다룰 예정이다.

Query

Query를 이용하여 조건에 맞는 Entity를 검색하고, 페이징을 구현 할 수 있다.

일반적인 쿼리의 사용법은 아래와 같다. BaasioQuery를 생성하고, 값을 셋팅해 준 후에 query(또는 queryInBackground)를 실행해주면 된다.

    BaasioQuery *query = [BaasioQuery queryWithCollection:@"tests"];
    [query setLimit:10];
    [query setProjectionIn:@"name, title"];
    [query setOrderBy:@"name" order:BaasioQuerySortOrderASC];
    [query setWheres:@"name = 'gary'"];

    [query queryInBackground:^(NSArray *array) {
        NSLog(@"array : %@", array.description);
    }
    failureBlock:^(NSError *error) {
        NSLog(@"fail : %@", error.localizedDescription);
    }];    

이 쿼리는 MySQL의 SQL 쿼리와 같다.

	select 
		name, title
	from 
		tests
	where
		name = 1 
	order by
		 name asc 
	limit 10 

페이징

baas.io는 게시판의 페이징을 구현 할 수는 없지만, 타임라인과 같이 전/후 페이지 조회는 할 수 있다.

내부적으로 cursor을 이용하기 때문에 query(queryInBackground)를 한번 한 후,

next(nextInBackground), prev(prevInBackground)를 이용하여 다음 Array를 가져 올 수 있다.

Group Query

BaasioQuery.queryWithGroup를 이용하여 Group에 속한 회원을 조회하는 쿼리 할 수 있다.

아래 예제는 students Group에 속한 회원을 조회하는 쿼리

    BaasioQuery *query = [BaasioQuery queryWithGroup:@"students"];
    [query queryInBackground:^(NSArray *array) {
                    NSLog(@"array : %@", array.description);
                }
                failureBlock:^(NSError *error){
                    NSLog(@"fail : %@", error.localizedDescription);
                }];

Connect Query

BaasioQuery.queryWithRelationship를 이용하여 연결 된 Entities를 쿼리 할 수 있다.

아래 예제는 blogEntity에서 아이디가 fd0c96dc-8573-11e2-9f13-06fd000000c2이고, blogWithComment라는 이름으로 연결된 Entity들을 조회하는 쿼리

    BaasioQuery *query = [BaasioQuery queryWithRelationship:@"blogEntity"
                                                   withUUID:@"fd0c96dc-8573-11e2-9f13-06fd000000c2"
                                               withRelation:@"blogWithComment"];
    [query queryInBackground:^(NSArray *array){
                    NSLog(@"array : %@", array.description);
              }
              failureBlock:^(NSError *error){
                    NSLog(@"fail : %@", error.localizedDescription);
              }];

File

File 기능은 file Collection을 통해 지원되며, 파일들을 업/다운로드 및 수정/삭제를 할 수 있다.

파일 Upload

    NSData *data = [@"Baas.io 조쿰 좋음! 15/800" dataUsingEncoding:NSUTF8StringEncoding];
   
    BaasioFile *file = [[BaasioFile alloc] init];
    file.data = data;
    file.filename = @"테스트.txt";
    file.contentType = @"application/json";
    [file setObject:@"cetauri" forKey:@"writer"];
    [file setObject:@"/testFilder" forKey:@"dir"];

    [file fileUploadInBackground:^(BaasioFile *file) {
                        NSLog(@"success : %@", file.uuid);
                    }
                    failureBlock:^(NSError *error) {
                        NSLog(@"error : %@", error.localizedDescription);
                    }
                    progressBlock:^(float progress) {
                        NSLog(@"progress : %f", progress);
                    }];
    

파일 Download

    NSString *uuid = @"......";
	
    // 다운로드 위치
    NSString *path = [NSString stringWithFormat:@"%@/1.txt", NSTemporaryDirectory()];
    
    BaasioFile *file = [[BaasioFile alloc] init];
    file.uuid = uuid;
    [file fileDownloadInBackground:path
          successBlock:^(NSString *downloadPath) {
              NSLog(@"success : %@", downloadPath);
         }
         failureBlock:^(NSError *error) {
             NSLog(@"error : %@", error.localizedDescription);
         }
         progressBlock:^(float progress){
             NSLog(@"progress : %f", progress);
         } ];
    

파일 수정 (Blob)

    NSString *uuid = @"......";
    
    BaasioFile *file = [[BaasioFile alloc] init];
    file.uuid = uuid;
    file.data = [@"Updated Baas.io is great!" dataUsingEncoding:NSUTF8StringEncoding];
    file.filename = @"A.txt";
    [file setObject:@"Kwon oh sang" forKey:@"owener"];
    [file fileUpdateInBackground:^(BaasioFile *entity){
                NSLog(@"success : %@", entity.description);
            }
            failureBlock:^(NSError *error) {
                NSLog(@"error : %@", error.localizedDescription);
            }
            progressBlock:^(float progress){
               NSLog(@"progress : %f", progress);
            }];
            

파일 정보 보기

    NSString *uuid = @"......";
    
    BaasioFile *file = [[BaasioFile alloc] init];
    file.uuid = uuid;
    [file getInBackground:^(BaasioFile *file) {
                NSLog(@"success : %@", file.description);
            }
            failureBlock:^(NSError *error) {
                NSLog(@"error : %@", error.localizedDescription);
            }];

파일 정보 수정

    NSString *uuid = @"......";
    
    BaasioFile *file = [[BaasioFile alloc] init];
    file.uuid = uuid;
    [file setObject:@"권오상" forKey:@"realname"];
    [file setObject:@"cetauri" forKey:@"nickname"];
    [file updateInBackground:^(BaasioFile *entity){
                    NSLog(@"success : %@, %@", entity.description, entity.filename);
                }
                failureBlock:^(NSError *error) {
                    NSLog(@"error : %@", error.localizedDescription);
                }];
                

파일 삭제

    NSString *uuid = @"......";

    BaasioFile *file = [[BaasioFile alloc] init];
    file.uuid = uuid;
    [file deleteInBackground:^(void) {
                    NSLog(@"Delete success.");
                }
                failureBlock:^(NSError *error) {
                    NSLog(@"error : %@", error.localizedDescription);
                }];
                

Push

Push 기능은 devices Collection을 통해 지원되며, bass.io 포털에서 인증서 정보를 설정한 후에 사용이 가능하다.

iOS의 경우 APNS (Apple Push Notification Services)을 사용하여 각각의 단말까지 전송을 지원하며 예약발송, 개별 발송 및 tag 별 발송 (예: 남자만, 여자만 등등)이 가능하다.

APNS 관련 정보는 다음 링크를 참조하여 주시고, 푸시서비스의 전반적인 상세 설명은 별도로 제공되는 Push Notification 개발자 가이드를 참고하여 주시기 바랍니다.

APNS (Apple Push Notification Service) Guide

Push 사용

푸쉬를 사용할 시점에 아래 코드를 실행해준다. 로그인이 되어 있다면 등록 시점에 로그인 정보가 같이 전송 되기 때문에 로그인이 성공한 후에 아래 코드를 실행해주면 된다.

단 Push를 개인별로 아닌 단체 공지 형식으로만 사용하려면 아무데나 넣으면 된다. (AppDelegate의 didFinishLaunchingWithOptions에 넣는걸 추천한다.)

[BaasioPush registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert];

위의 코드를 실행하면 AppDelegate의 didRegisterForRemoteNotificationsWithDeviceToken 메소드를 통해 deviceToken을 받을 수 있다. didRegisterForRemoteNotificationsWithDeviceToken 메소드에 아래와 같이 작성하면 서버에 deviceToken을 등록 할 수 있다.

tag를 사용하면 tag별로 사용자에게 Push를 보낼 수 있는데, tag를 안 쓸때는 nil을 주면 된다.

또한 이미 등록이 되어 있는 경우에는 skip한다.

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
	// 테그를 이용하여 테그별로 사용자에게 Push를 보낼 수 있다.
    NSArray *tags = @[@"male", @"cetauri"];
    BaasioPush *push = [[BaasioPush alloc] init];
    [push didRegisterForRemoteNotifications:deviceToken
                                       tags:tags
                               successBlock:^(void) {
                                   NSLog(@"success");
                               }
                               failureBlock:^(NSError *error) {
                                   NSLog(@"fail : %@", error.localizedDescription);
                               }];
}

Push 해제 (단말 등록 취소)

로그 아웃 시에 호출해주면 된다.

- (void)unregisterForRemoteNotifications:(void (^)(void))successBlock
                            failureBlock:(void (^)(NSError *error))failureBlock;
                            
    BaasioPush *push = [[BaasioPush alloc] init];
    [push unregisterForRemoteNotifications:^(void) {
                                   NSLog(@"success");
                               }
                               failureBlock:^(NSError *error) {
                                   NSLog(@"fail : %@", error.localizedDescription);
                               }];

발송

Push 발송은 sendPushInBackgroundsendPush method에 BaasioMessage 객체를 넘기면 된다.

BaasioMessage를 이용하여 예약발송, 테그별 및 플랫폼별 또는 사용자에게 직접 Push를 보낼 수 있는 기능을 구현 할 수 있다.

    BaasioPush *push = [[BaasioPush alloc] init];
    BaasioMessage *message = [[BaasioMessage alloc]init];
    ...	
    [push sendPush:message error:&error];
    	
    if (!error) {
        //성공
        NSLog(@"Success");
    } else {
        //실패
        NSLog(@"Error: %@", error.localizedDescription);
    }
    BaasioPush *push = [[BaasioPush alloc] init];
    BaasioMessage *message = [[BaasioMessage alloc]init];
    ...	
    [push sendPushInBackground:message
                  successBlock:^(void) {
                      NSLog(@"success.");
                  }
                  failureBlock:^(NSError *error) {
                      NSLog(@"fail : %@", error.localizedDescription);
                  }];

예약 발송

BaasioMessage.reserve에 NSDateComponents를 넘겨주면 그 시각에 맞추어 예약 발송이 된다.

아래 예제는 2013/5/8일에 User.uuid가 f5df22f9-547e-11e2-b5a4-06ebb80000ba 인 회원에게, 2개의 badge표시가 된 push를 보내는 예제

    BaasioPush *push = [[BaasioPush alloc] init];
    BaasioMessage *message = [[BaasioMessage alloc]init];

    NSDateComponents *reserve = [[NSDateComponents alloc]init];
    reserve.year = 2013;
    reserve.month = 5;
    reserve.day = 8;
    reserve.hour = 0;
    reserve.minute = 0;

    message.reserve = reserve;
    message.alert = @"Push 메시지";
    message.badge = 2;
    message.to = [NSMutableArray arrayWithObject:@"f5df22f9-547e-11e2-b5a4-06ebb80000ba"];
    
    [push sendPushInBackground:message
                  successBlock:^(void) {
                      NSLog(@"success.");
                  }
                  failureBlock:^(NSError *error) {
                      NSLog(@"fail : %@", error.localizedDescription);
                  }];
                  

테그별 발송

BaasioMessage.to에 tag 이름을 입력하면 된다.

    BaasioPush *push = [[BaasioPush alloc] init];
    BaasioMessage *message = [[BaasioMessage alloc]init];

    message.badge = 1;
    message.to = [NSMutableArray arrayWithObject:@"man"];
    
    [push sendPushInBackground:message
                  successBlock:^(void) {
                      NSLog(@"success.");
                  }
                  failureBlock:^(NSError *error) {
                      NSLog(@"fail : %@", error.localizedDescription);
                  }];

개별 발송

BaasioMessage.to에 사용자의 UUID를 입력하면 된다. 1번 발송에 10개 제한이 있으니 유의하기 바란다.

    BaasioPush *push = [[BaasioPush alloc] init];
    BaasioMessage *message = [[BaasioMessage alloc]init];
    message.badge = 1;
    message.to = @[@"f5df22f9-547e-11e2-b5a4-06ebb80000ba", @"a5df22f9-547e-11e2-b5a4-06ebb80000b1", ...];
    
    [push sendPushInBackground:message
                  successBlock:^(void) {
                      NSLog(@"success.");
                  }
                  failureBlock:^(NSError *error) {
                      NSLog(@"fail : %@", error.localizedDescription);
                  }];

Push On/Off

Push Off

서버에 여전히 디바이스가 등록 되어 있지만, Push를 받지 않는다.

    BaasioPush *push = [[BaasioPush alloc] init];
    [push pushOffInBackground:^(void) {
                      NSLog(@"success.");
                  }
                  failureBlock:^(NSError *error) {
                      NSLog(@"fail : %@", error.localizedDescription);
                  }];

Push On

Push를 받을 수 있도록 활성화 한다.

    BaasioPush *push = [[BaasioPush alloc] init];
    [push pushOnInBackground:^(void) {
                      NSLog(@"success.");
                  }
                  failureBlock:^(NSError *error) {
                      NSLog(@"fail : %@", error.localizedDescription);
                  }];

Tag 수정

등록된 Tag를 수정한다.

    BaasioPush *push = [[BaasioPush alloc] init];
    [push tagUpdateInBackground:@[@"NewTag"]
                   successBlock:^{
                       NSLog(@"success.");
                   }
                   failureBlock:^(NSError *error) {
                       NSLog(@"fail : %@", error.localizedDescription);
                   }];

Help

BaasioHelp 클래스를 이용하여 간편하게 고객센터 서비스를 구현할 수 있다. 고객센터의 대한 자세한 내용은 고객센터 가이드를 참고하면 된다.

또한 모바일에서 고객센터를 쉽게 구현하실 수 있도록 고객센터 UI 라이브러리를 제공하고 있다.

직접 UI를 구현하기 보다는 아래 링크에서 UI 템플릿을 받아 수정하기를 권한다.

고객선테는 비동기 API만 제공된다. 혹시 동기식 API가 필요하다고 생각되면, 먼저 진짜 필요한지 아키텍쳐에 대해서 고민해보기 바란다.

고민 후에도 진짜로 필요하다고 결정되면 github clone 하여 직접 구현해서 쓸 수 있다.

도움말(FAQ) 목록

    
    BaasioHelp *helpdesk = [[BaasioHelp alloc]init];
    [helpdesk getHelpsInBackground:^(NSArray *array) {
                             NSLog(@"array : %@", array.description);
                         }
                         failureBlock:^(NSError *error) {
                            NSLog(@"fail : %@", error.localizedDescription);
                         }];
    

도움말(FAQ) 검색

    
    NSString *query = @"검색";
    BaasioHelp *helpdesk = [[BaasioHelp alloc]init];
    [helpdesk searchHelpsInBackground:query
                         successBlock:^(NSArray *array) {
                             NSLog(@"array : %@", array.description);
                         }
                         failureBlock:^(NSError *error) {
                            NSLog(@"fail : %@", error.localizedDescription);
                         }];
    

도움말(FAQ) 상세내용 보기

    NSString *uuid = @"cf334051-2dee-47ef-b787-2d7f5a889db0"; // help entity uuid
	
    BaasioHelp *helpdesk = [[BaasioHelp alloc]init];
    [helpdesk getHelpDetailInBackground:uuid
             successBlock:^(NSDictionary *dictionary) {
                 NSLog(@"dictionary : %@", dictionary);
             }
             failureBlock:^(NSError *error) {
                 NSLog(@"fail : %@", error.localizedDescription);
             }];

문의하기

    BaasioHelp *helpdesk = [[BaasioHelp alloc]init];

    [helpdesk sendQuestionInBackground:email
                               content:content
                          successBlock:^(void) {
                              NSLog(@"success.");
                          }
                          failureBlock:^(NSError *error) {
                              NSLog(@"error : %@", error.localizedDescription);
                          }];
                          

Error

Error handling에 대해서는 계속 고민중이지만, 좋은 아이디어 있으면 Pull Requests를 바란다. 우리는 항상 열려있다.

Error code와 localizedDescription를 통해서 에러를 확인 할 수 있다.

   
    failureBlock:^(NSError *error) {
        NSLog(@"description : %@", error.localizedDescription);
        NSLog(@"code : %i", error.code);
    }                     
    

Rest Network API

SimpleNetworkManager 클래스를 이용하면 추가적인 네트워크 라이브러리 없이 간편하게 외부 리소스 접근이 가능하다.

또한 SDK에서 제공하지 못하는 Rest API도 이 클래스를 이용하면 확장하여 사용이 가능하다.

iOS SDK는 AFNetworking를 기본 네트워크 라이브러리로 사용한다.

그렇기 때문에 한 프로젝트에 AFNetworking와 baas.io iOS SDK를 동시에 사용하면 "duplicate symbol" 에러가 발생한다.

그 경우, AFNetworking에 관련된 *.m파일을 지우면 해결 할 수 있다.

Basic

    NSString *path = @"https://api.usergrid.com/status";
    NSDictionary *params = @{@"key" : @"value2"};
    
    NSError *e;
    NSString *response = [[SimpleNetworkManager sharedInstance]connectWithHTTPSync:path
                                                                        withMethod:@"GET"
                                                                            params:params
                                                                      headerFields:nil
                                                                             error:&e];
    NSLog(@"error : %@", e);
    NSLog(@"response : %@", response);
    NSString *path = @"https://api.usergrid.com/status";
    NSDictionary *params = @{@"key" : @"value2"};
    
    [[SimpleNetworkManager sharedInstance]connectWithHTTP:path
                                               withMethod:@"GET"
                                                   params:params
                                             headerFields:nil
                                                  success:^(NSString *response) {
                                                      NSLog(@"success : %@", response);
                                                  }
                                                  failure:^(NSError *error) {
                                                      NSLog(@"error : %@", error.localizedDescription);
                                                  }];

Header 정보 추가

만일 사이트에서 header에 Authorization라는 키로 인증 값을 넘겨야 한다면, 아래와 같이 하면 된다.

그 외에도 content-type과 같은 값을 아래와 같이 headerFields형태의 NSDictionary를 만들어 넘기면 된다.

    NSString *path = @"https://api.usergrid.com/status";
    
    NSDictionary *headerFields = @{@"Authorization" : @"어쩌고 저쩌고"};
    [[SimpleNetworkManager sharedInstance]connectWithHTTP:path
                                               withMethod:@"GET"
                                                   params:nil
                                             headerFields:headerFields
                                                  success:^(NSString *response) {
                                                      NSLog(@"success : %@", response);
                                                  }
                                                  failure:^(NSError *error) {
                                                      NSLog(@"error : %@", error.localizedDescription);
                                                  }];

기본 baas.io의 인증 정보

여러분이 인증 정보(로그인 후)를 가지고 이 API를 사용한다면, 내부적으로 인증 정보를 실어서 보낼 것입니다.

즉 추가로 인증에 대한 작업을 하지 않아도 됩니다.

UIImageView 지원

AFNetworking에서는 UIImageView 클래스에 외부의 이미지를 비동기로 로딩하는 기능이 있다.

UIImageView+AFNetworking.h라는 이름의 category로 되어 있는데, baas.io SDK에서도 이것을 이용하여 구현하였다.

다음과 같이 import만 하면 UIImageView 클래스가 확장되어 아래의 메소드들을 쓸수 있다.

#import "UIImageView+Baasio.h"
    UITableViewCell *listCell nil;
    NSURL url = [NSURL URLWithString:@"http://asia.olympus-imaging.com/products/dslr/e520/sample/images/sample_03.jpg"];
	
	//중간 생략
    
	// UIImageView에는 원래 imageWithURL 메소드가 없다.
    [listCell.imageView imageWithURL:url
                    placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

BaasioFile의 경우 아래와 같이 손 쉽게 사용이 가능하다.

    UITableViewCell *listCell nil;
    BaasioFile *file = nil;
	
	//중간 생략
    
	// UIImageView에는 원래 imageWithBaasioFile 메소드가 없다.
    [listCell.imageView imageWithBaasioFile:file
                           placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

Next Step

baas.io SDK 로 구현된 샘플 프로젝트들이 있다. 아직은 몇개 안되지만 계속 제작하여 공개 할 계획이다.

모든 baas.io 관련 소스는 다음 주소에서 얻을 수 있다.

https://github.com/baasio