2014. 5. 22. 18:29

IOS 의 UILabel의 가로정렬은 아주 간단하게 가능하지만~


세로정렬은 기본적으로 제공하지 않는다.. (가로정렬처럼 align 때려박듯이 한방에 되었으면 좋겠다만)


덕분에 세로정렬을 위해서는 골을 좀 싸메야 한다.!


우선 UILabel의 SIze를 알아내서 Frame을 셋팅하는 방법으로 하면 된단다.


- (void)setUILabel:(UILabel *)myLabel withMaxFrame:(CGRect)maxFrame withText:(NSString *)theText usingVerticalAlign:(int)vertAlign 

{

  CGSize stringSize =

  [theText sizeWithFont:myLabel.font constrainedToSize:maxFrame.sizelineBreakMode:myLabel.lineBreakMode];

    

    switch (vertAlign) {

        case 0// vertical align = top

            myLabel.frame = 

              CGRectMake(myLabel.frame.origin.xmyLabel.frame.origin.ymyLabel.frame.size.widthstringSize.height);

            break;

            

        case 1// vertical align = middle

            // don't do anything, lines will be placed in vertical middle by default

            break;

            

        case 2// vertical align = bottom

            myLabel.frame = CGRectMake(myLabel.frame.origin.x

                                       (myLabel.frame.origin.y + myLabel.frame.size.height) - stringSize.height

                                       myLabel.frame.size.width

                                       stringSize.height

                                       );

            break;

    }

    

    myLabel.text = theText;

} 

 

끝.

Posted by 은돌군
2014. 3. 6. 15:53


View에 slide 효과 주는 코드!


    [UIView beginAnimations:nil context:NULL]; //애니메이션 시작

    [UIView setAnimationDuration:0.2]; //슬라이드 동작하는 시간

    [UIView setAnimationDelay:0.2]; //얼마의 시간후 슬라이드 에니메이션이 동작하는지!

    [UIView commitAnimations]; //애니메이션 동작!


Posted by 은돌군
2014. 2. 11. 13:19

문자열 치환 코드입니다~

. 을 , 로 바꾸는 한줄짜리 코드입니다.~

참고하세용~


  strDist = [strDist stringByReplacingOccurrencesOfString:@"." withString:@","]; 


Posted by 은돌군
2014. 2. 6. 18:31

긴 문자열 내부에 짧은 단어 같은 문자열이 존재 하는지 확인하는 방법이다.

함수로 한번에 딱!! 하는 방법이 있을거라 생각했는데 찾지 못했다.


다음 코드는 jsonString 이라는 문자열 내부에 login 이라는 단어가 포함되어 있는 지 찾는 코드이다.

한번 보시면 이해되리라 믿는다 ㅎㅎ


NSString *jsonString = [[NSString alloc] initWithFormat:@"login Success or fail?"];

NSRange rangeValue = [jsonString rangeOfString:@"login" options:NSCaseInsensitiveSearch];

if(rangeValue.length > 0)

{

//문자열이 내부에 존재함

}

else

{

//문자열이 내부에 존재하지 않음

}



Posted by 은돌군
2014. 1. 24. 19:28

Sample Code 를 다운받아 빌드하는 도중 아래와 같은 문제가 발생함.


Error 중 다음과 같은 에러가 존재..

"Xcode cannot run using the selected device."

"Choose a destination with a supported architecture in order to run on this device"


해결방법으로


1. 최저 Compile target Version 이 현재 Target Version 보다 높게 설정되어 있는 경우,


2. build settings 의 Valid Architectures 가 잘못 설정되어 있는 경우 위와 같은 에러가 발생할 수 있다고 함.

3. build options 의 Compiler for C/C++/Objective-C Default compile (Apple LLVM 5.0) Setting 을 함으로 해결


나의 경우는 3번 문제였음.. 참고하세요~

Posted by 은돌군
2014. 1. 22. 16:45

ios 7.0 , xcode 5.02 기준 작업


2014.1.22.수.16:00

LinkedIn의 경우는 자체 ios SDK 가 없으며, Web Base 의 Api만 제공해준다. (2014.1.22.수 기준)

그렇기 때문에 직접적으로 ios에 사용할 수는 없으며, 다른 OpenSource의 ios SDK 를 사용해야 할 것같다.


우선 첫 Sample Project & ios Open Source 를 찾았다.!!

Sample Project Name : OAuth1Sample 

KinveyKit.framework 와 libUairShip-1.4.0.a 를 링크하여 사용하는 셈플이었다. 

url : http://devcenter.kinvey.com/ios/samples

셈플자체는 동작이 잘 된다.

하지만 이 셈플 프로젝트의 SDK 들을 내 App 에 추가하려니 문제가 생긴다.

Linker command failed with exit code 1 

갑갑한 Link Error 가 생긴다.

Link Error의 문제점 

1. framework 가 없는 경우

 셈플프로젝트와 framework 확인정도?

2. 타겟 App 문제

 타겟 잡혀있나 확인

3. Library Version 문제

 검색중..

4. Xcode 자체적 버그

 해결 불능..ㅠㅠ


2014.1.23.목.11:46

libUairShip-1.4.0.a 의 버젼은 최신버젼이 3.0.0 까지 있다. 

libUairShip 최신버젼을 셈플 코드에 이식해 보았으나, 셈플 코드의 KinveyKit.framework 에서 에러가 떨어진다.

즉, 위의 셈플 코드에서 사용하는 KinveyKit.framework에서 libUairShip-1.4.0 버젼에서만 사용하는 클래스를 사용하는 듯 하다;;


그리고 Link Error 가 나는 이유는.. libUairShip-1.4.0 버젼에서 사용하는 클래스들과, xcode 5.02 에서 사용하는 framework가 달라서 나는게 아닐까?

추측중.. 그럼 어쩌냐;;;


우선 셈플을 다른걸 찾아봐야하나??


14:04

인터넷을 뒤적뒤적이다가 kinveyKit.framework 의 최신버젼을 찾음! - (Ver. 1.25)

기존 셈플에서 사용한 KinveyKit  버젼이 몇버젼인지 모르겟으나 framework 용량이 두배차이!!

그러면, 버젼차이가 많이나서 코드도 완전 다를라나???ㅠ
암튼 우선 프레임 워크 이식... libuairship 없이 이식, & libuairship 3.0.0 과 함께 이식 시도 해볼것!! 우선 셈플에!!

url : http://www.kinvey.com/

- web service 를 위한 sdk 로 보여짐..


15:00

결국 현재상태에서의 문제는 libUairShip-1.4.0.a 를 사용해야 하는데 내 App에 이 아카이브를 추가만 하면 문제가 된다.

그럼우선 Sample Project 를 Xcode5에서 생성 및 framework도 Xcode5에서 주는 아이들과 함께 Framework 만 넣어보면?

Sample 과 같은 framework 를 Xcode5에서 주는 framework 로 사용하고 LibUairShip-1.4.0.a 를 함께 프로젝트에 포함하더라도

문제가 발생하지 않는다.! 그럼 Framework 충돌 문제인가?

그렇다면, 이식한, 즉 libUairShip-1.4.0.a 를 추가했을때 link error 가 났던 App의 framework를 모두 추가해보자!

근데 빈 프로젝트에 필요한 프레임워크만 모두 로드하고 실행하면.... 잘된다..........헐;;;

잘되는게 더 멘붕이다;;;;;;


추측 내 App의 최소 빌드 버젼 셋팅이 다른경우?


16:44

그래.. 더러워서 그냥;; linkedin API 쓰자;;;

framework 붙이다가 아카이브 붙이다가 .. 날샐라;;'

모르믄 손발이 고생해야지...


2014.1.24.금 21:21

LinkedIn API 의 직접구현은 찾아보다가 포기..

oauth 1.0, oauth 2.0 이라는 표준을 사용하며, 토큰이 여러번 왔다갔다 하는 과정을 거침으로, 직접 구현하믄 최소 한달은 걸릴 것이라 생각됨;;ㅠㅠ

고로 기존에 받아 놨던 Sample Code 들 중에서 해결할 수 있는 에러들은 해결해 보자는 생각으로 기존 Sample Code Error check

Error 중 다음과 같은 에러가 존재..

"Xcode cannot run using the selected device."

"Choose a destination with a supported architecture in order to run on this device"

해결방법으로

build options 의 Compiler for C/C++/Objective-C Default compile (Apple LLVM 5.0) Setting 을 함으로 해결

이 외에 시도해 볼 수 있는 일이

최저 Compile target Version 이 현재 Target Version 보다 높게 설정되어 있는 경우,

또한 build settings 의 Valid Architectures 가 잘못 설정되어 있는 경우 위와 같은 에러가 발생할 수 있다고 함.

아무튼, 위 문제를 해결하여 멀쩡한 Sample Code 를(제대로 동작하는) 찾음...

이제 이식만 하면되겟지!!? 라고 바라고 있음.ㅠ


작업완료


https://github.com/PrincessPolymath/LinkedIn-OAuth-Sample-Client

다음 셈플을 가지고 이식하였음.. developer.linkedin.com 에서 제공하는 기본 셈플임..

결론은 그동안 다른 셈플로 이짓저짓한건 다 삽질???..ㅠㅠ


저 셈플을 현재버젼(xcode5.02) 버젼에서 실행시키게 되면

"Xcode cannot run using the selected device."

"Choose a destination with a supported architecture in order to run on this device"

이런 오류가 발생하는데 이 오류에 대해선 이곳에 정리해 놓았음.

http://jjangdali.tistory.com/entry/ObjectCIphoneXcode-cannot-run-using-the-selected-device-Error-%ED%95%B4%EA%B2%B0%EB%B0%A9%EB%B2%95


그리고 암호화쪽 코드가 .c 코드로 되어 있는데 이부분을 다 .m 으로 바꾸어주면 됨..

이 간단한 걸 몰라서 몇일동안 삽질.... 하아;;;


그리고 코드를 그대로~ 넣으면됨...

다른 셈플들 or 다른 소셜쪽과는 달리 이 sample example 은

delegate에는 추가할 코드가 없음.

셈플의 Oauthloginview.h, m, xib 를 내 앱에 그대로 복사후 사용하고,

셈플프로젝트의 코드를 그대로 사용하면 됨;;;





Posted by 은돌군
2014. 1. 22. 14:05

IOS 공부를 시작하면서, 이것 저것 구현을 해보다가,

문득 생각난 안드로이드의 생명주기..

역시 아이폰도 검색해보니 한번에 나오더라~

자동 호출되는 아이들이 있고, 그런 것들을 이용하여 개발하는 것이 말단 개발자의 숙명이려니... 암튼

IOS의 생명주기는 아래와 같다.


출처 : http://j2enty.tistory.com/76


# Application 생명주기
 먼저 아이폰에서 구분지은 Application 생명주기를 나열하자면 아래와 같습니다. 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 => 어플리케이션이 처음 실행될 때. (처음 메모리상에 올라가게 될 때를 말함) 

- (void)applicationDidBecomeActive:(UIApplication *)application
 => 어플리케이션이 활성화 될 때, 
  즉 didFinishLaunchingWithOption 호출 직후, 어플리케이션이 백그라운드로 돌아갔다가 다시 불러질 때 호출

- (void)applicationWillResignActive:(UIApplication *)application
 => 어플리케이션이 백그라운드로 들어가기 직전(홈버튼을 누른 직후)에 호출 됨

- (void)applicationDidEnterBackground:(UIApplication *)application
 => 어플리케이션이 백그라운드로 완전히 들어갔을 때 호출됨

- (void)applicationWillEnterForeground:(UIApplication *)application
 => 어플리케이션이 다시 활성되 되기 직전에 호출됨
    (백그라운드 상에서 다시 어플리케이션이 활성되 되면 willEnterForeground 호출 후 applicationDidBecomeActive 호출)

- (void)applicationWillTerminate:(UIApplication *)application 
 => 어플리케이션이 완전히 종료되기 직전에 호출 됨


이렇게 크게 6가지의 상태로 구분 질 수 있습니다.

바로 이 부분 부터 개발자가 컨트롤하여 어플리케이션을 구현 할 수있습니다.

여기서 친구가 물어본 부분을 결론 짓자면 어플리케이션의 시작은 사용자가 어플리케이션을 클릭해서 main.m이 호출되는 순간부터라고 할 수 있습니다. 하지만 개발자 입장에서 즉, 개발자가 컨트롤 할 수 있는 어플리케이션의 시작은 AppDelegate의 didFinishLaunchingWithOptions 라고 할 수 있습니다.


여기서 한가지 팁을 추가로 남기겠습니다.
Xcode에서 프로젝트를 생성하면 기본적으로 AppDelegate의 didFinishLaunchingWithOptions 메소드 안에 아래와 같은 코드가 구현됩니다.

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

{

    self.window = [[[UIWindow allocinitWithFrame:[[UIScreen mainScreenbounds]] autorelease];

    self.viewController = [[[ViewController allocinitWithNibName:@"ViewController" bundle:nilautorelease];

    self.window.rootViewController = self.viewController;

    [self.window makeKeyAndVisible];

    return YES;

}



바로 이 부분을 두개의 파트로 또 나눌 수 있습니다.
사용자가 어플리케이션의 첫 화면을 볼 수 있는 순간은 바로 [self.window makeKeyAndVisible]; 가 호출 되는 순간입니다.
바로 이 메소드를 전/후로 하여 사용자에게 화면이 보여지기 전에 해야 할 것들을 정리 할 수 있고 사용자에게 화면이 보여진 후에 할 것을 정리할 수 있을 것입니다. 


# 뷰 컨트롤러의 생명주기는 아래와 같습니다.
 

- (void)loadView
뷰 컨트롤러에 보여지는 컨트롤러들을 생성하거나 추가할 때 적당한 부분 

- (void)viewWillAppear:(BOOL)animated
뷰 컨트롤러가 사용자에게 보여지기 직전에 호출(복수 호출 가능) 
loadView 다음에 호출 됨 

- (void)viewDidLoad
viewWillAppear 다음에 호출 됨 (단 한번만 호출됨) 

- (void)viewDidAppear:(BOOL)animated
viewDidLoad 다음에 호출 됨(복수 호출 가능)

- (void)viewWillDisappear:(BOOL)animated
해당 뷰컨트롤러가 사라지기 직전에 호출됨  

- (void)viewDidUnload
viewWillDisappear 이후에 호출됨

- (void)viewDidDisappear:(BOOL)animated
viewDidUnload 이후에 호출됨



Application 생명주기와 합쳐보자면 Application에서 뷰 컨트롤러를 메모리상에 올리고 사용자에게 보여지도록 하면 Application 생명주기와는 별도로 ViewController만의 생몀주기가 또 돌아가게 됩니다. 

Posted by 은돌군
2014. 1. 21. 11:06

Undefined symbols for architecture i386:

  "_OBJC_CLASS_$_CMMotionManager", referenced from:

      objc-class-ref in GooglePlus(GPPSpamSignal.o)

ld: symbol(s) not found for architecture i386

clang: error: linker command failed with exit code 1 (use -v to see invocation)


위에 글이 나의 에러!!..
xcode architectures 의 valid architecture 의 내 앱에 "i386" string 추가후

아래 글을 따라하면 해결된다.



출처 : http://appcofe.blogspot.kr/2013/10/fix-build-problem-of-google-plus-sdk-in.html



Fix the Build Problem of Google Plus SDK in XCode (iOS)

Fix:Google Plus SDK building problem in XCode 
If you meet the following build issues (in red color)

Please add "CoreText.framework" and "CoreMotion.framework" and "ALAssetsLibrary.framework" into "Targets"->"Build Phases"->"Link Binary with Libraries"
And rebuild your xcode project.
Undefined symbols for architecture armv7:  "_CTFramesetterCreateFrame", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView runAtPosition:] in GooglePlus(GPPStyledTextView.o)  "_CTLineGetTypographicBounds", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)  "_CTLineGetGlyphRuns", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView runAtPosition:] in GooglePlus(GPPStyledTextView.o)  "_CTRunGetAttributes", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView hitTest:withEvent:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView handleTouch:] in GooglePlus(GPPStyledTextView.o)  "_OBJC_CLASS_$_CMMotionManager", referenced from:      objc-class-ref in GooglePlus(GPPSpamSignal.o)  "_CTFramesetterCreateWithAttributedString", referenced from:      -[GPPStyledTextView heightForWidth:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView runAtPosition:] in GooglePlus(GPPStyledTextView.o)  "_CTFramesetterSuggestFrameSizeWithConstraints", referenced from:      -[GPPStyledTextView heightForWidth:] in GooglePlus(GPPStyledTextView.o)  "_CTLineCreateWithAttributedString", referenced from:      _gpp_newTruncatedLine in GooglePlus(GPPStyledTextView.o)  "_CTFrameGetLineOrigins", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView runAtPosition:] in GooglePlus(GPPStyledTextView.o)  "_kCTForegroundColorAttributeName", referenced from:      -[GPPHtmlSnippet parser:foundCharacters:] in GooglePlus(GPPHtmlSnippet.o)      _gpp_newTruncatedLine in GooglePlus(GPPStyledTextView.o)  "_CTLineGetStringRange", referenced from:      _gpp_newTruncatedLine in GooglePlus(GPPStyledTextView.o)  "_CTLineCreateTruncatedLine", referenced from:      _gpp_newTruncatedLine in GooglePlus(GPPStyledTextView.o)  "_CTFrameGetLines", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView runAtPosition:] in GooglePlus(GPPStyledTextView.o)  "_kCTFontAttributeName", referenced from:      -[GPPHtmlSnippet parser:foundCharacters:] in GooglePlus(GPPHtmlSnippet.o)      _gpp_newTruncatedLine in GooglePlus(GPPStyledTextView.o)  "_CTFontManagerRegisterGraphicsFont", referenced from:      ___45+[NSBundle(GPP3PAdditions) gpp_registerFonts]_block_invoke in GooglePlus(NSBundle+GPP3PAdditions.o)  "_CTFontCreateWithName", referenced from:      +[UIFont(GPPAdditions) gpp_CTFontForFontSize:attributes:] in GooglePlus(UIFont+GPPAdditions.o)      _gpp_newTruncatedLine in GooglePlus(GPPStyledTextView.o)  "_CTRunGetTypographicBounds", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)      -[GPPStyledTextView runAtPosition:] in GooglePlus(GPPStyledTextView.o)  "_CTLineDraw", referenced from:      -[GPPStyledTextView drawRect:] in GooglePlus(GPPStyledTextView.o)  "_OBJC_CLASS_$_ALAssetsLibrary", referenced from:      objc-class-ref in GooglePlus(NSData+GPPAdditions.o)      objc-class-ref in GooglePlus(UIDevice+GPPAdditions.o)ld: symbol(s) not found for architecture armv7clang: error: linker command failed with exit code 1 (use -v to see invocation)


Posted by 은돌군
2014. 1. 20. 19:06
# 추가해야하는 FrameWorks
> 다운받아서 추가해야 하는 frameWorks
GoogleOpenSource.framework, GooglePlus.bundle, GooglePlus.framework

> 자체라이브러리에서 추가해야 하는 frameworks
CoreMotion.framework, MobileCoreServices.framework, CoreText.framework, AssetsLibrary.framework

Build Setting 의 other linker flag 에 -ObjC 옵션 추가할것 (빠지면 Link Error 발생함)



AppDelegate.h


#import <GooglePlus/GooglePlus.h>


@interface AppDelegate : UIResponder <UIApplicationDelegateGPPDeepLinkDelegate>


- (void)didReceiveDeepLink:(GPPDeepLink *)deepLink;


AppDelegate.m


#import <GooglePlus/GooglePlus.h>

...

static NSString * const GooglePlusAppClientID = @"App Key";


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

{

[GPPSignIn sharedInstance].clientID = GooglePlusAppClientID;

...

[GPPDeepLink setDelegate:self];

[GPPDeepLink readDeepLinkAfterInstall];

}


ViewController.h


#import <GooglePlus/GooglePlus.h>


- (IBAction)OnTouchUpGooglePlusLogin:(id)sender;



ViewController.m


#import <GoogleOpenSource/GoogleOpenSource.h>

#import <GooglePlus/GooglePlus.h>


/* For GooglePlusLogin

 by YG.Seo 2014.1.16 */

- (IBAction)OnTouchUpGooglePlusLogin:(id)sender

{

    GPPSignIn *signIn = [GPPSignIn sharedInstance];

    signIn.shouldFetchGooglePlusUser = YES;

    signIn.shouldFetchGoogleUserEmail = YES;

    signIn.delegate = self;

    

    if([signIn authentication] == nil)

    {

        [signIn authenticate];

    }

    else

    {

        [signIn disconnect];

    }

}


- (void)finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error {

    if (error) {

        NSLog(@"Received error %@ and auth object %@",error, auth);

        return;

    }

    m_strGooglePlusAccount = [GPPSignIn sharedInstance].userEmail;

    NSLog(@"GooglePlusUser : %@", m_strGooglePlusAccount);


}

- (void)didDisconnectWithError:(NSError *)error {

    if (error) {

        NSLog(@"Status:Failed to disconnect: %@", error);

    } else {

        NSLog(@"Status: Disconnected");

    }

}

Posted by 은돌군
2014. 1. 20. 19:03

Android의 broadcast와 비슷한 유형의 개념으로 어플끼리의 통신을 사용하는 듯 하다.

이 부분을 ios 에서는 InterOP라 하며,

delegate 의 함수들 중.. 아래 함수의 개념에 대해 알아보려 하다가 나왔다.

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{

 return URL;

}


개념은 찾아보니 잘 나와있더라~,

나는.. url을 동시에 여러개를 써야하는데.. 형태가 return 형이네;;; OTL 

아무튼 개념은 아래와 같고!!!

여러개 쓰는건 내일 해보고!!!!

오늘은 퇴근하자!!!


출처 : http://iceemperor.springnote.com/pages/6512823

iOS 어플리케이션간 통신방법

 

 iOS 는 어플리케이션간 통신을 위하여 URL 을 사용하는 방법을 쓴다. URL 의 프로토콜 부분에 해당하는 부분, 예를 들면 http:// 의 http 와 같은 부분을 특정 어플리케이션이 연결하는 것으로 해당 어플리케이션에 메시지를 전달할 수 있다.

 즉 TestApplication1 이라는 어플리케이션이 다른 어플리케이션으로부터 어떤 메시지를 받고 싶다면 testapp1 이라는 이름으로 등록해 두면, 다른 어플리케이션이 testapp1:// 과 같은 URL 형태로 요청을 할 경우 iOS 가 TestApplication 을 찾아 실행하는 것이다.

개요

 간단한 흐름을 정리하면 다음과 같다.

1. 메시지를 받을 어플리케이션의 info.plist 에, 특정 URL 프로토콜과 바인딩하도록 등록한다.
2. 어플리케이션이 설치되면 iOS 는 프로토콜 목록에 위의 어플리케이션과 프로토콜 이름을 연결해 둔다.
3. 특정 어플리케이션이 UIApplication 의 openURL 을 사용할 경우, iOS 는 URL 내에 존재하는 프로토콜을 보고, 이와 바인딩 된 어플리케이션이 있다면 그 어플리케이션을 실행한다. 이미 실행되어 있다면 이미 실행중인 인스턴스를 활성화시킨다.
4. 실행한 어플리케이션의 UIApplicationDelegate 단에 handleOpenURL 이 정의되어 있으면 이것을 호출하고, 이 함수의 인자로, 어플리케이션 실행을 요청한 URL 데이터를 보내준다.

 따라서 URL 형식에서 프로토콜 부분을 통해 실행할 어플리케이션을 결정하고, 나머지 형식에 데이터를 실어보내는 방식으로 통신을 수행할 수 있다.

 다만 이 방식은 해당 어플리케이션에 메시지를 전달하기만 하고 거기서 아무것도 하지 않으므로, 반환값을 받는다거나 하는 등의 피드백을 받기 위해서는 역시 호출하는 쪽에서도 똑같이 위의 방법을 구현해 주어야만 한다. 즉 두 어플리케이션이 요청-응답 방식으로 통신하려면 둘 다 위의 방식으로 등록작업을 수행해야 한다.


 URL 방식으로 상호 데이터를 전달하지만, http 가 프로토콜 구조상의 한계로 4096 바이트밖에 전달받지 못하는 것과는 달리, 이것은 어플리케이션간 데이터를 전달받는 구조이기 때문에 딱히 길이 제한이 존재하지 않는다. 다만 문자열로 선처리하는 구조상 (즉 받은 데이터를 모조리 메모리상에 적재할 수 밖에 없는 구조) 과도하게 큰 데이터는 어플리케이션 실행 자체에 문제를 일으킬 수 있다.


구체적 방법
  1. 어플리케이션에서 먼저 리스닝을 할 수 있도록 설정을 수행한다.

    1. 어플리케이션-info.plist 를 연다.
    2. URL types 항목을 추가한다.
    3. 추가된 URL types 항목을 열고 Item 0 를 다시 열어 URL identifier 와 URL Schemes 를 추가한다.
    4. URL identifier 의 값에 현재 어플리케이션의 번들 도메인을 그대로 넣어두면 된다. (보통은)
    5. URL Schemes 를 다시 열고, Item 0 항목의 값에, URL 로 호출 시 반응하게 될 프로토콜 이름을 적는다. 예를 들어 bindingaddr 이렇게 이름을 적었다면, URL 호출 시 bindingaddr:// 을 앞에 붙여서 호출하였을 때 이 어플리케이션이 실행될 것이다.

      1. 여기서 생각할 수 있는 것이, 이 어플리케이션 하나가 여러 개의 URL 프로토콜에 반응하도록 만들 수 있을 것이라는 점이다. 즉 URL Schemes 에 기본으로 제공되는 Item 0 외에 다른 아이템을 더 추가하면 여러 개의 프로토콜에도 반응하게 할 수 있다.
    6. 다음 메소드를 추가한다.

      -(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url

  2. 다른 어플리케이션으로부터, 등록한 어플리케이션을 호출한다.

    1. URL 로 사용할 적절한 문자열을 생성한다.

      1. 호출할 어플리케이션의 URL Schemes 에 등록된 값 중 하나를 프로토콜로 설정한다.
        예) bindingapps2://
      2. 어플리케이션에 전달할 메시지를 문자열로 적절히 기술한다. URL 구조를 따르는 형식으로 메시지를 만든다면 쉽게 메시지를 파싱할 수 있을 것이다.
    2. NSURL 을 이용하여 URL 개체로 만든다.

      1. [NSURL URLWithString:문자열] 을 사용하면 반환값으로 돌려준다.
    3. 어플리케이션에서 지원하는 openURL 을 사용하여 OS 에게 URL 호출을 부탁한다.

      1. [[UIApplication sharedApplication] openURL:생성한주소]


Posted by 은돌군