본문 바로가기
프로그래밍/iOS

UIActivityViewController를 이용하여 다른 앱과 컨텐츠 공유하기

by 백룡화검 2013. 2. 28.

참고::

http://mobiledevelopertips.com/user-interface/uiactivityviewcontroller-sharing-content-on-ios-6-part-1.html

http://www.toyship.org/archives/959

http://uiactivities.com/

관련::

http://warmz.tistory.com/824

샘플소스::


UIActivityViewController는 iOS 6에서 새롭게 추가된 클래스로써, 이 클래스를 활용하면 뷰 컨트롤러가 컨텐츠를 여러 서비스(OS 내 설치된 어플리케이션)에게 공유할 수 있게 해준다. 공유 대상 서비스의 범위는 SMS 또는 이메일, 클립보드 복사하기 (이것들은 모두 iOS 내부 어플리케이션)과 iOS 소셜 프레임워크로 추가된 트위터(Twitter), 페이스북(Facebook), 웨이보(Weibo)가 해당된다.

 UIActivityViewController 는 UIDocumentInteractionController와 성격이 다르다. 두 클래스 모두 데이터를 다른 앱과 공유한다는 목적은 같으나 UIDocumentInteractionController는 리소스 파일 기반의 공유(예를 들어 윈도우의 특정 확장자에 대한 연결 프로그램)이고 UIActivityViewController는 공유할 수 있는 앱은 한정되어 있으나 객체 기반의 공유이다. UIActivityViewController가 공유할 수 있는 앱은 위에서 설명하였듯이 기본 앱(SMS, 이메일, 클립보드)과 소셜 프레임워크 지원 대상(트위터, 페이스북, 웨이보)이며 그외의 어플리케이션을 추가하고 싶으면 대상 어플리케이션이 UIActivityViewController를 상속한 클래스를 제공해야 한다.

UIActivityViewController 생성

어떠한 객체를 공유하는 방법은 간단하다. 아래 코드를 참고.


- (IBAction)btnTouched:(id)sender
{
    if( ![UIActivity class])
    {
            // UIActivity supported in iOS6
        // show error dialog
        return;
    }
     
    NSString *text = @"Hello World!";
    NSArray* actItems = [NSArray arrayWithObjects:
                         text, nil];
     
    UIActivityViewController *activityView = [[[UIActivityViewController alloc]
                                               initWithActivityItems:actItems
                                               applicationActivities:nil]
                                              autorelease];
     
    [self presentViewController:activityView
                       animated:YES
                     completion:nil];
}

위 코드를 보면 "Hello World"라는 NSString 객체를 NSArray에 담아 ActivityItem으로써 전달하고 있다. 이외에 UIImage 와 같은 객체도 전달가능하다. 전달 받은 어플리케이션은 모달 뷰 컨트롤러로 실행된다.


당신이 원한다면 특정 앱을 Action Sheet에 나오지 않게 제외할 수 있다.


// Tailor the list of services displayed
activityView.excludedActivityTypes = @[
    UIActivityTypeAssignToContact,
    UIActivityTypeMessage,
    UIActivityTypeSaveToCameraRoll,
    UIActivityTypePrint,
    UIActivityTypePostToWeibo,
    UIActivityTypeCopyToPasteboard];


위 코드처럼 UIActivityViewController 객체에 excludedActivityTypes를 지정할 수 있는데 이 flag들은 UIActivity.h에 아래와 같이 정의되어 있다.


UIKIT_EXTERN NSString *const UIActivityTypePostToFacebook   NS_AVAILABLE_IOS(6_0); // text, images, URLs
UIKIT_EXTERN NSString *const UIActivityTypePostToTwitter    NS_AVAILABLE_IOS(6_0); // text, images, URLs
UIKIT_EXTERN NSString *const UIActivityTypePostToWeibo      NS_AVAILABLE_IOS(6_0); // text, images, URLs
UIKIT_EXTERN NSString *const UIActivityTypeMessage          NS_AVAILABLE_IOS(6_0); // text
UIKIT_EXTERN NSString *const UIActivityTypeMail             NS_AVAILABLE_IOS(6_0); // text, image, file:// URLs
UIKIT_EXTERN NSString *const UIActivityTypePrint            NS_AVAILABLE_IOS(6_0); // image, NSData, file:// URL, UIPrintPageRenderer, UIPrintFormatter, UIPrintInfo
UIKIT_EXTERN NSString *const UIActivityTypeCopyToPasteboard NS_AVAILABLE_IOS(6_0); // text, image, NSURL, UIColor, NSDictionary
UIKIT_EXTERN NSString *const UIActivityTypeAssignToContact  NS_AVAILABLE_IOS(6_0); // image
UIKIT_EXTERN NSString *const UIActivityTypeSaveToCameraRoll NS_AVAILABLE_IOS(6_0); // image, video


Action Sheet에 다른 어플리케이션 추가하기

Action Sheet에는 flag로 선언된 iOS내부 어플리케이션를 제외한 다른 어플리케이션을 추가할 수 있다. 그러나 추가하려는 어플리케이션의 Scheme(스키마)가 공개되어 있어야 하고 그 어플리케이션이 제공하는 UIActivityViewController를 상속한 CustomActivityViewController 클래스가 있어야 한다. 여기서는 크롬 iOS 버전의 공개된 스키마를 이용한 예제를 살펴보겠다. 크롬 iOS 버전 스키마는 아래 URL에서 참고할 것.

https://google-developers.appspot.com/chrome/mobile/docs/ios-links

ARChromeActivity



#import 
 
@interface ARChromeActivity : UIActivity
 
@end
#import "ARChromeActivity.h"
 
@implementation ARChromeActivity
{
    NSURL *_activityURL;
}
 
// ActionSheet에 보여질 크롬 앱 이미지
- (UIImage *)activityImage
{
    return [UIImage imageNamed:@"ARChromeActivity"];
}
 
// ActionSheet에 보여질 크롬 앱 제목
- (NSString *)activityTitle
{
    return @"Open in Chrome";
}
 
// ActionSheet에 보여지는 앱은 iOS에 설치된 상태여야한다.
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
{
    BOOL isExistChrome = [[activityItems lastObject] isKindOfClass:[NSURL class]]
    && [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"googlechrome://"]];
 
    return isExistChrome;
}
 
- (void)prepareWithActivityItems:(NSArray *)activityItems
{
    _activityURL = [activityItems lastObject];
}
 
// 앱 실행
- (void)performActivity
{
    NSURL *inputURL = _activityURL;
    NSString *scheme = inputURL.scheme;
     
    // Replace the URL Scheme with the Chrome equivalent.
    NSString *chromeScheme = nil;
    if ([scheme isEqualToString:@"http"])       chromeScheme = @"googlechrome";
    else if ([scheme isEqualToString:@"https"]) chromeScheme = @"googlechromes";
     
    // Proceed only if a valid Google Chrome URI Scheme is available.
    if (chromeScheme)
    {
        NSString *absoluteString = [inputURL absoluteString];
        NSRange rangeForScheme = [absoluteString rangeOfString:@":"];
        NSString *urlNoScheme =
        [absoluteString substringFromIndex:rangeForScheme.location];
        NSString *chromeURLString =
        [chromeScheme stringByAppendingString:urlNoScheme];
        NSURL *chromeURL = [NSURL URLWithString:chromeURLString];
         
        NSLog(@"%@", chromeURL);
         
        // Open the URL with Chrome.
        [[UIApplication sharedApplication] openURL:chromeURL];
         
        [self activityDidFinish:YES];
    }
}
 
- (void)activityDidFinish:(BOOL)completed
{
    NSLog(@"ctivityDidFinish");
    [super activityDidFinish:completed];
}
 
@end

위 소스는 UIActivityViewController를 실행할 어플리케이션 내에 포함되어 있어야 한다. 단순히 스키마를 이용하여 다른 앱과 통신하는 것이기 때문이다.



- (void)showActivities:(id)sender
{
    // 전송할 데이터
    NSURL *urlToShare = [NSURL URLWithString:@"http://alextrob.net/"];
    NSArray *activityItems = [NSArray arrayWithObject:urlToShare];
     
    // 실행 가능한 어플리케이션 액티비티 추가
    ARChromeActivity *chromeActivity = [[ARChromeActivity alloc] init];
    NSArray *applicationActivities = [NSArray arrayWithObject:chromeActivity];
     
    UIActivityViewController *activityVC =
            [[UIActivityViewController alloc] initWithActivityItems:activityItems
                                              applicationActivities:applicationActivities];
     
    [self presentViewController:activityVC animated:YES completion:nil];
}

구글 크롬, 인스타그램, 핀북 등 각 유명 어플리케이션의 UIActivity Provider 클래스는 아래 사이트에서 공유되고 있다. 참고할 것.

http://uiactivities.com/