輕量級社會化分享openShare源碼解析

開篇

關于社會化分享,一般用友盟比較多挂据,但是也有其他的實現(xiàn)方式以清,這里介紹一下
openShare ,可以不利用官方SDK,直接進行分享崎逃。和友盟相比包小了太多掷倔,不過貌似沒法統(tǒng)計,各有特色吧个绍。

正文

openShare整體結構.png

如上圖openShare的整體結構主要分為兩大部分勒葱,openShare 和各大平臺的分類浪汪。每個平臺都去擴展OpenShare的類方法,來很好的保證平臺的增加和整體功能的完善等凛虽。
我們通過新浪微博和QQ的登錄和分享來介紹openShare的使用以及對源碼的實現(xiàn)方法的理解死遭。

新浪微博分享

AppDelegate配置

首先導入頭文件并注冊相關的key

 //第一步:注冊key
    [OpenShare connectQQWithAppId:@"1103194207"];
    [OpenShare connectWeiboWithAppKey:@"402180334"];
    [OpenShare connectWeixinWithAppId:@"wxd930ea5d5a258f4f"];
    [OpenShare connectRenrenWithAppId:@"228525" AndAppKey:@"1dd8cba4215d4d4ab96a49d3058c1d7f"];
    [OpenShare connectAlipay];//支付寶參數(shù)都是服務器端生成的,這里不需要key.

然后設置分享的回調(diào)方法代碼如下涩维,這里等下分析OpenShare+Weibo文件的時候詳細再說殃姓。

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    //第二步:添加回調(diào)
    if ([OpenShare handleOpenURL:url]) {
        return YES;
    }
    //這里可以寫上其他OpenShare不支持的客戶端的回調(diào),比如支付寶等瓦阐。
    return YES;
}

ViewController中的調(diào)用

在示例代碼中登錄和分享的調(diào)用方法如下:

   UIView *ret=[[UIView alloc] initWithFrame:frame];
    UIButton *auth=[self button:@"登錄" WithCenter:CGPointMake(frame.size.width/2, 40)];
    [ret addSubview:auth];
    [auth addEventHandler:^(id sender) {
        [OpenShare WeiboAuth:@"all" redirectURI:@"http://openshare.gfzj.us/" Success:^(NSDictionary *message) {
            ULog(@"微博登錄成功:\n%@",message);
        } Fail:^(NSDictionary *message, NSError *error) {
            ULog(@"微博登錄失敗:\n%@\n%@",message,error);
        }];
    } forControlEvents:UIControlEventTouchUpInside];

   UIButton *textShare=[self button:@"分享純文本" WithCenter:CGPointMake(auth.center.x, calcYFrom(auth)+40)];
    [ret addSubview:textShare];
    textShare.tag=1001;
    [textShare addTarget:self action:@selector(weiboViewHandler:) forControlEvents:UIControlEventTouchUpInside];
    
    UIButton *imgShare=[self button:@"分享圖片" WithCenter:CGPointMake(auth.center.x, calcYFrom(textShare)+40)];
    [ret addSubview:imgShare];
    imgShare.tag=1002;
    [imgShare addTarget:self action:@selector(weiboViewHandler:) forControlEvents:UIControlEventTouchUpInside];
    
    UIButton *newsShare=[self button:@"分享新聞" WithCenter:CGPointMake(auth.center.x, calcYFrom(imgShare)+40)];
    [ret addSubview:newsShare];
    newsShare.tag=1003;
    [newsShare addTarget:self action:@selector(weiboViewHandler:) forControlEvents:UIControlEventTouchUpInside];

//微博分享的實現(xiàn)方法
-(void)weiboViewHandler:(UIButton*)btn{
    OSMessage *message=[[OSMessage alloc]init];
    message.title=@"hello openshare (message.title)";
    if (btn.tag>=1002) {
        message.image=testImage;
    }
    if (btn.tag==1003) {
        message.link=@"http://openshare.gfzj.us/";
    }
    [OpenShare shareToWeibo:message Success:^(OSMessage *message) {
        ULog(@"分享到sina微博成功:\%@",message);
    } Fail:^(OSMessage *message, NSError *error) {
        ULog(@"分享到sina微博失敗:\%@\n%@",message,error);
    }];
}

這里首先先說一下登錄的事件添加方式

   [auth addEventHandler:^(id sender) {
        [OpenShare WeiboAuth:@"all" redirectURI:@"http://openshare.gfzj.us/" Success:^(NSDictionary *message) {
            ULog(@"微博登錄成功:\n%@",message);
        } Fail:^(NSDictionary *message, NSError *error) {
            ULog(@"微博登錄失敗:\n%@\n%@",message,error);
        }];
    } forControlEvents:UIControlEventTouchUpInside];

方法的添加是由下圖中的UIControl+Blocks文件中實現(xiàn)的


UIControl+Blocks

在.h中創(chuàng)建了- (void)addEventHandler:(ActionBlock)handler forControlEvents:(UIControlEvents)controlEvents;
以及ActionBlock蜗侈。我們點進.m,可以看到主要由兩個方法組成代碼如下:

- (void)addEventHandler:(ActionBlock)handler forControlEvents:(UIControlEvents)controlEvents
{
    objc_setAssociatedObject(self, &UIButtonHandlerKey, handler, OBJC_ASSOCIATION_COPY_NONATOMIC);
    [self addTarget:self action:@selector(callActionHandler:) forControlEvents:controlEvents];

};
}
- (void)callActionHandler:(id)sender
{
    ActionBlock handler = (ActionBlock)objc_getAssociatedObject(self, &UIButtonHandlerKey);
    if (handler) {
        handler(sender);
    }
}

首先

  objc_setAssociatedObject(self, &UIButtonHandlerKey, handler, OBJC_ASSOCIATION_COPY_NONATOMIC);

為runtime的動態(tài)屬性的添加,各個參數(shù)對應的解釋如下

      * @param self  需要添加關聯(lián)的對象
     *  @param UIButtonHandlerKey     添加的唯一標識符
     *  @param handler   關聯(lián)的對象
     *  @param OBJC_ASSOCIATION_COPY_NONATOMIC  關聯(lián)的策略,是個枚舉

這句話可以理解為,以OBJC_ASSOCIATION_COPY_NONATOMIC的關聯(lián)策略為自己添加一個標識符為UIButtonHandlerKey的handler對象睡蟋。
點進這句話我們可以看到系統(tǒng)對應的關聯(lián)策略的枚舉踏幻,有以下幾種形式

    typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
     OBJC_ASSOCIATION_ASSIGN = 0,           //< Specifies a weak reference to the associated object.
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //< Specifies a strong reference to the associated object.
                                               The association is not made atomically.
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   //< Specifies that the associated object is copied.
                                              The association is not made atomically.
    OBJC_ASSOCIATION_RETAIN = 01401,       //< Specifies a strong reference to the associated object.
                                              The association is made atomically.
    OBJC_ASSOCIATION_COPY = 01403          //< Specifies that the associated object is copied.
                                              The association is made atomically.
};

OK,接下來在看對應的添加的callActionHandler事件中的代碼

ActionBlock handler = (ActionBlock)objc_getAssociatedObject(self, &UIButtonHandlerKey);
  if (handler) {//判斷block是否為null 防止crash
        handler(sender);
    }

ActionBlock通過標示符UIButtonHandlerKey戳杀,得到的之前的管理屬性该面,然后判斷如果block不為空,進行下一步的操作信卡。

OpenShare+Weibo

我們從調(diào)用處著手開始分析一下源碼中的一些方法隔缀。登錄和分享,最先調(diào)起的兩個方法分別為:
登錄

+(void)WeiboAuth:(NSString*)scope redirectURI:(NSString*)redirectURI Success:(authSuccess)success Fail:(authFail)fail;

分享調(diào)起方法

+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;

點擊這兩個方法我們首先進入到的是OpenShare+Weibo傍菇,一個專門用來處理微博的分類中猾瘸,我們可以看到一共有以下4個方法:

+(void)connectWeiboWithAppKey:(NSString *)appKey;
+(BOOL)isWeiboInstalled;
/**
 *  分享到微博,微博只支持三種類型:文本/圖片/鏈接丢习。根據(jù)OSMessage自動判定想分享的類型牵触。
 *
 *  @param msg     要分享的msg
 *  @param success 分享成功回調(diào)
 *  @param fail    分享失敗回調(diào)
 */
+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;

/**
 *  微博登錄OAuth
 *
 *  @param scope       scope,如果不填寫咐低,默認是all
 *  @param redirectURI 必須填寫揽思,可以通過http://open.weibo.com/apps/402180334/info/advanced編輯(后臺不驗證,但是必須填寫一致)
 *  @param success     登錄成功回調(diào)
 *  @param fail        登錄失敗回調(diào)
 */
+(void)WeiboAuth:(NSString*)scope redirectURI:(NSString*)redirectURI Success:(authSuccess)success Fail:(authFail)fail;

分別用來注冊微博相關的key见擦,判斷是否安裝以及主要的分享登錄钉汗。
平臺和key的設置

每個分類中設置不同的schema,區(qū)分平臺
+(void)connectWeiboWithAppKey:(NSString *)appKey{
    [self set:schema Keys:@{@"appKey":appKey}];
}
調(diào)用openShare的設置方法
+(void)set:(NSString*)platform Keys:(NSDictionary *)key{
    if (!keys) {
        keys=[[NSMutableDictionary alloc] init];
    }
    keys[platform]=key;
}
  • 分享的方法
    下面通過分享方法鲤屡,介紹一下核心的分享的實現(xiàn)方式
+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
    if (![self beginShare:schema Message:msg Success:success Fail:fail]) {
        return;
    }
    NSDictionary *message;
    //根據(jù)不同的分享形式 設置不同的字典格式 
    if ([msg isEmpty:@[@"link" ,@"image"] AndNotEmpty:@[@"title"] ]) {
        //text類型分享
        message= @{
                   @"__class" : @"WBMessageObject",
                   @"text" :msg.title
                   };
    }else if ([msg isEmpty:@[@"link" ] AndNotEmpty:@[@"title",@"image"] ]) {
        //圖片類型分享
        message=@{
                  @"__class" : @"WBMessageObject",
                  @"imageObject":@{
                          @"imageData":[self dataWithImage:msg.image]
                          },
                  @"text" : msg.title
                  };
        
    }else if ([msg isEmpty:nil AndNotEmpty:@[@"title",@"link" ,@"image"] ]) {
        //鏈接類型分享
        message=@{
                  @"__class" : @"WBMessageObject",
                  @"mediaObject":@{
                          @"__class" : @"WBWebpageObject",
                          @"description": msg.desc?:msg.title,
                          @"objectID" : @"identifier1",
                          @"thumbnailData":msg.thumbnail ? [self dataWithImage:msg.thumbnail] : [self dataWithImage:msg.image  scale:CGSizeMake(100, 100)],    //三目運算
                          @"title": msg.title,
                          @"webpageUrl":msg.link
                          }
                  
                  };
    }
    NSString *uuid=[[NSUUID UUID] UUIDString];
    NSArray *messageData=@[
                           @{@"transferObject":[NSKeyedArchiver archivedDataWithRootObject:@{
                                                                                             @"__class" :@"WBSendMessageToWeiboRequest",
                                                                                             @"message":message,
                                                                                             @"requestID" :uuid,
                                                                                             }]},
                           @{@"userInfo":[NSKeyedArchiver archivedDataWithRootObject:@{}]},
                           
                           @{@"app":[NSKeyedArchiver archivedDataWithRootObject:@{ @"appKey" : [self keyFor:schema][@"appKey"],@"bundleID" : [self CFBundleIdentifier]}]}
                           ];
    [UIPasteboard generalPasteboard].items=messageData;
    [self openURL:[NSString stringWithFormat:@"weibosdk://request?id=%@&sdkversion=003013000",uuid]];
}

通過代碼我們可以看到主要步驟為:判斷參數(shù)是否存在-->設置分享方式 -->設置messageData并歸檔信息-->把數(shù)據(jù)放到粘貼板上 -->打開網(wǎng)址( [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
的方式)
下面我們分析是如何設置分享方式的儡湾,代碼如下:

if ([msg isEmpty:@[@"link" ,@"image"] AndNotEmpty:@[@"title"] ]) {
        //text類型分享
        message= @{
                   @"__class" : @"WBMessageObject",
                   @"text" :msg.title
                   };
    }

msg代表的OSMessage對象包含內(nèi)容如下:

@interface OSMessage : NSObject
@property NSString* title;
@property NSString* desc;
@property NSString* link;
@property UIImage *image;
@property UIImage *thumbnail;
@property OSMultimediaType multimediaType;
//for 微信
@property NSString* extInfo;
@property NSString* mediaDataUrl;
@property NSString* fileExt;
@property (nonatomic, strong) NSData *file;   /// 微信分享gif/文件
/**
 *  判斷emptyValueForKeys的value都是空的,notEmptyValueForKeys的value都不是空的执俩。
 *
 *  @param emptyValueForKeys    空值的key
 *  @param notEmptyValueForKeys 非空值的key
 *
 *  @return YES/NO
 */
-(BOOL)isEmpty:(NSArray*)emptyValueForKeys AndNotEmpty:(NSArray*)notEmptyValueForKeys;
@end

OSMessage是用來保存分享的數(shù)據(jù)信息的對象徐钠。可以通過其中包含的內(nèi)容來進行區(qū)分分享的內(nèi)容類型役首。而其中:-(BOOL)isEmpty:(NSArray)emptyValueForKeys AndNotEmpty:(NSArray)notEmptyValueForKeys;介紹如下:

-(BOOL)isEmpty:(NSArray*)emptyValueForKeys AndNotEmpty:(NSArray*)notEmptyValueForKeys{
    @try {
        if (emptyValueForKeys) {
            for (NSString *key in emptyValueForKeys) {
                if ([self valueForKeyPath:key]) {//valueForKeyPath 可以獲取OSMessage中相同key的元素
                             return NO;   
 }
        }
        if (notEmptyValueForKeys) {
            for (NSString *key in notEmptyValueForKeys) {
                if (![self valueForKey:key]) {//取OSMessage對象里 key對應的內(nèi)容 如果不存在返回NO
                    return NO;
                }
            }
        }
        return YES;
    }
    @catch (NSException *exception) {
        NSLog(@"isEmpty error:\n %@",exception);
        return NO;
    }
}

方法實現(xiàn)的目的是 判斷emptyValueForKeys的value都是空的尝丐,notEmptyValueForKeys的value都不是空的显拜。valueForKeyPath判斷給定的數(shù)組中的內(nèi)容是否有OSMessage中相同key的元素,如果有的話返回NO爹袁,走下一種分享模式远荠。valueForKey判斷給定的內(nèi)容是否也存在于OSMessage的對象中,如果存在返回YES失息。
對下面代碼中的翻譯為:

 if ([msg isEmpty:@[@"link" ,@"image"] AndNotEmpty:@[@"title"] ]) {
        //text類型分享
        message= @{
                   @"__class" : @"WBMessageObject",
                   @"text" :msg.title
                   };
    }

如果OSMessage對象中不包含譬淳,link,image盹兢,只包含title邻梆,則設置的分享格式是純文本分享,同時設置分享的字典格式绎秒。

    [UIPasteboard generalPasteboard].items=messageData;

在新浪微博的分享中以上述方式浦妄,把要分享的內(nèi)容放至剪貼板上。

  • 回調(diào)方法

接下來看回調(diào)函數(shù)

+(BOOL)Weibo_handleOpenURL{
}

主要代碼如下:

    if ([url.scheme hasPrefix:@"wb"]) {
        NSArray *items=[UIPasteboard generalPasteboard].items;
        NSMutableDictionary *ret=[NSMutableDictionary dictionaryWithCapacity:items.count];
        for (NSDictionary *item in items) {
            for (NSString *k in item) {
                ret[k]=[k isEqualToString:@"transferObject"]?[NSKeyedUnarchiver unarchiveObjectWithData:item[k]]:item[k];
            }
        }
        NSDictionary *transferObject=ret[@"transferObject"];
        if ([transferObject[@"__class"] isEqualToString:@"WBAuthorizeResponse"]) {//通過反歸檔 取出的類名  登錄
            //auth
            if ([transferObject[@"statusCode"] intValue]==0) {
                if ([self authSuccessCallback]) {
                    [self authSuccessCallback](transferObject);
                }
            }else{
                if ([self authFailCallback]) {
                    NSError *err=[NSError errorWithDomain:@"weibo_auth_response" code:[transferObject[@"statusCode"] intValue] userInfo:transferObject];
                    [self authFailCallback](transferObject,err);
                }
            }
        }else if ([transferObject[@"__class"] isEqualToString:@"WBSendMessageToWeiboResponse"]) {//分享
            //分享回調(diào)
            if ([transferObject[@"statusCode"] intValue]==0) {
                if ([self shareSuccessCallback]) {
                    [self shareSuccessCallback]([self message]);
                }
            }else{
                if ([self shareFailCallback]) {
                    NSError *err=[NSError errorWithDomain:@"weibo_share_response" code:[transferObject[@"statusCode"] intValue] userInfo:transferObject];
                    [self shareFailCallback]([self message],err);
                }
            }
        }
        return YES;
    }

主要邏輯為:取出剪貼板上內(nèi)容 -->根據(jù)遍歷循環(huán)取出-->根據(jù)之前設置的字典格式區(qū)分內(nèi)容-->設置回調(diào)信息

一次分享的整體流程
  • 01:對應平臺設置key 和相關平臺設置
+(void)set:(NSString*)platform Keys:(NSDictionary *)key
  • 02:對應平臺取值方法
+(NSDictionary *)keyFor:(NSString*)platform{
    return [keys valueForKey:platform]?keys[platform]:nil;
}
  • 03:創(chuàng)建創(chuàng)建要分享的OSMessage對象
 OSMessage *message=[[OSMessage alloc]init];
  • 04:調(diào)去分享微博的方法

  • 05:分享方法的調(diào)起內(nèi)部實現(xiàn)

+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail
  • 06:區(qū)分分享方式见芹,設置分享的字典格式剂娄,內(nèi)容以items的形式復制至剪貼板
 [UIPasteboard generalPasteboard].items=messageData;
  • 07:拼接uuid 打開軟件
  [self openURL:[NSString stringWithFormat:@"weibosdk://request?id=%@&sdkversion=003013000",uuid]];
  • 08 走OpenShare中回調(diào)的hook方法確定是否有回調(diào)
+(BOOL)handleOpenURL:(NSURL*)openUrl{
}
  • 09分享結束回調(diào),取出剪貼板的數(shù)據(jù),做回調(diào)處理
實現(xiàn)原理
  • A程序通過Uri跳轉(zhuǎn)到對應的分享程序B里玄呛。
  • 在B里面阅懦,他讀取從粘貼板里的數(shù)據(jù)和根據(jù)uri做對應的分享處理。
  • 分享完徘铝,B把分享的狀態(tài)結果也放到粘貼板里耳胎。然后,根據(jù)A之前設好的uri庭砍,又跳回到A應用中。
  • 然后A把粘貼板的數(shù)據(jù)讀出來混埠,就知道分享是成功還是失敗了怠缸。
hook方法
+(BOOL)handleOpenURL:(NSURL*)openUrl{
    returnedURL=openUrl;
    for (NSString *key in keys) {
        SEL sel=NSSelectorFromString([key stringByAppendingString:@"_handleOpenURL"]);
        if ([self respondsToSelector:sel]) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                                        [self methodSignatureForSelector:sel]];
            [invocation setSelector:sel];  
            
            [invocation setTarget:self];
            [invocation invoke];  
            BOOL returnValue;
            [invocation getReturnValue:&returnValue];
            if (returnValue) {
                return YES;
            }
        }else{
            NSLog(@"fatal error: %@ is should have a method: %@",key,[key stringByAppendingString:@"_handleOpenURL"]);
        }
    }
    return NO;
}

我們主要看一下下面這個方法中的內(nèi)容

+(BOOL)handleOpenURL:(NSURL*)openUrl{  }

創(chuàng)建了一個SEL對象,來獲取之前分類中不同的handleOpenURL方法钳宪,通過NSSelectorFromString 來判斷 未實現(xiàn)的方法是不是我們想要動態(tài)添加的方法如:

+(BOOL)Weibo_handleOpenURL{}

如果實現(xiàn)了揭北,利用NSInvocation來直接調(diào)用這個消息,在設置萬簽名吏颖,和設置對象之后搔体,執(zhí)行[invocation invoke],然后根據(jù)Weibo_handleOpenURL方法中的返回內(nèi)容通過getReturnValue來確定有無回調(diào)方法半醉。

  • NSInvocation介紹
    NSInvocation對象只能使用其類方法來初始化疚俱,不可使用alloc/init方法。它執(zhí)行調(diào)用之前缩多,需要設置兩個方法:setSelector: 和setArgument:atIndex呆奕,簡單的NSInvocation使用方法如下:
  SEL   selector = @selector(Test2);

    methodSign = [[self class] instanceMethodSignatureForSelector:selector];
    
    NSInvocation *mehtod2Invocation = [NSInvocation invocationWithMethodSignature:methodSign];
    
    [mehtod2Invocation setSelector:selector];
    
    [mehtod2Invocation invokeWithTarget:self];
    
    BOOL returnValue = 1;
    
    [mehtod2Invocation getReturnValue:&returnValue];
    
    NSLog(@"返回值:%ld",returnValue);



-(BOOL)Test2{
    
    return NO;
}

有返回值無參數(shù)類型的函數(shù)养晋,此處的打印數(shù)值應該是0,因為Test2的返回值是NO梁钾。

   //有返回值绳泉,有參數(shù)
    
    SEL  selector = @selector(Test3:);
    
    NSMethodSignature *method3Sign = [[self class] instanceMethodSignatureForSelector:selector];
    
    NSInvocation *method3Invocation = [NSInvocation invocationWithMethodSignature:method3Sign];
    
    [method3Invocation setTarget: self];
    
    [method3Invocation setSelector:selector];
    
    NSString *arg1 = @"testArg1";
    
    [method3Invocation setArgument:&arg1 atIndex:2];
    
    [method3Invocation invoke];
    
//    [method3Invocation setReturnValue:&arg1];
    [method3Invocation getReturnValue:&arg1];

    NSLog(@".....%@",arg1);


-(NSString *)Test3 :(NSString*)a{
    
    a= @"122334";
    
    NSLog(@"----%@",a);
    
    return a;
}

如果是 [method3Invocation getReturnValue:&arg1] 他的作用是獲取函數(shù)的返回結果,打印結果為

2017-06-22 16:14:40.850 01234567899[2884:103358] ----122334
2017-06-22 16:14:40.850 01234567899[2884:103358] .....122334

如果是 [method3Invocation setReturnValue:&arg1] 他的作用是設置函數(shù)的返回結果 函數(shù)表達式變?yōu)槿缦拢?/p>

-(NSString *)Test3 :(NSString*)a{
    NSLog(@"----%@",a);
    return a;
}

打印結果為

2017-06-22 16:17:28.261 01234567899[2924:105348] ----testArg1
2017-06-22 16:17:28.261 01234567899[2924:105348] .....testArg1

[invocation invoke]; 這個方法中姆泻,只要調(diào)用invocation的invoke方法零酪,就代表需要執(zhí)行NSInvocation對象中制定對象的指定方法,并且傳遞指定的參數(shù)拇勃。
至此我們基本說完了新浪微博分享的整體流程那么我們在大致說一下QQ分享的時候四苇,與新浪微博的區(qū)別。

QQ分享的區(qū)別

調(diào)用分享的主要函數(shù)舉例如下:

+(void)shareToQQFriends:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
    if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
        [self openURL:[self genShareUrl:msg to:0]];
    }
}

主要的區(qū)別在genShareUrl中

+(NSString*)genShareUrl:(OSMessage*)msg to:(int)shareTo{ }

數(shù)據(jù)的歸檔并放置到剪貼板的方法為[[UIPasteboard generalPasteboard] setData:data forPasteboardType:key];不同于新浪微博的 [UIPasteboard generalPasteboard].items=messageData;具體實現(xiàn)如下:

/**
 數(shù)據(jù)的歸檔 并放置剪貼板
 */
+(void)setGeneralPasteboard:(NSString*)key Value:(NSDictionary*)value encoding:(OSPboardEncoding)encoding{
    if (value&&key) {
        NSData *data=nil;
        NSError *err;
        switch (encoding) {
            case OSPboardEncodingKeyedArchiver://歸檔方式存儲
                data=[NSKeyedArchiver archivedDataWithRootObject:value];
                break;
            case OSPboardEncodingPropertyListSerialization://序列化
                data=[NSPropertyListSerialization dataWithPropertyList:value format:NSPropertyListBinaryFormat_v1_0 options:0 error:&err];
            default:
                NSLog(@"encoding not implemented");
                break;
        }
        if (err) {
            NSLog(@"error when NSPropertyListSerialization: %@",err);
        }else if (data){
            [[UIPasteboard generalPasteboard] setData:data forPasteboardType:key];///*data類型的數(shù)據(jù)放在粘貼板中潜秋,pasteboardType  類型 字符串*/
        }
    }
}

/**
 從剪貼板取出數(shù)據(jù)  并解檔
 */
+(NSDictionary*)generalPasteboardData:(NSString*)key encoding:(OSPboardEncoding)encoding{
    NSData *data=[[UIPasteboard generalPasteboard] dataForPasteboardType:key];//從剪貼板取出數(shù)據(jù)
    NSDictionary *dic=nil;
    if (data) {
        NSError *err;
        switch (encoding) {
            case OSPboardEncodingKeyedArchiver:
                dic= [NSKeyedUnarchiver unarchiveObjectWithData:data];
                break;
            case OSPboardEncodingPropertyListSerialization:
                dic=[NSPropertyListSerialization propertyListWithData:data options:0 format:0 error:&err];
            default:
                break;
        }
        if (err) {
            NSLog(@"error when NSPropertyListSerialization: %@",err);
        }
    }
    return dic;
}

并在打開軟件的過程中使用了base64編碼等蛔琅,其余的原理大致相同。
到這里峻呛,對openShare實現(xiàn)的過程和源碼有了大致的說明罗售,可以開心的使用啦。

00

后記

這篇介紹钩述,主要是自己對openShare寨躁,實現(xiàn)的一種認識,以及對源碼的理解牙勘,可能存在一定的錯誤和理解偏差职恳,希望積極指出。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末方面,一起剝皮案震驚了整個濱河市放钦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恭金,老刑警劉巖操禀,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異横腿,居然都是意外死亡颓屑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門耿焊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揪惦,“玉大人,你說我怎么就攤上這事罗侯∑饕福” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蒂培。 經(jīng)常有香客問我再愈,道長,這世上最難降的妖魔是什么护戳? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任翎冲,我火速辦了婚禮,結果婚禮上媳荒,老公的妹妹穿的比我還像新娘抗悍。我一直安慰自己,他們只是感情好钳枕,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布缴渊。 她就那樣靜靜地躺著,像睡著了一般鱼炒。 火紅的嫁衣襯著肌膚如雪衔沼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天昔瞧,我揣著相機與錄音指蚁,去河邊找鬼。 笑死自晰,一個胖子當著我的面吹牛凝化,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酬荞,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼搓劫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了混巧?” 一聲冷哼從身側響起枪向,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咧党,沒想到半個月后秘蛔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡凿傅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年缠犀,在試婚紗的時候發(fā)現(xiàn)自己被綠了数苫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聪舒。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖虐急,靈堂內(nèi)的尸體忽然破棺而出箱残,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布被辑,位于F島的核電站燎悍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏盼理。R本人自食惡果不足惜谈山,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宏怔。 院中可真熱鬧奏路,春花似錦、人聲如沸臊诊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抓艳。三九已至触机,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玷或,已是汗流浹背儡首。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留庐椒,地道東北人椒舵。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像约谈,于是被迫代替她去往敵國和親笔宿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結尾創(chuàng)建: 董瀟偉棱诱,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,690評論 0 9
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程泼橘,因...
    小菜c閱讀 6,373評論 0 17
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)迈勋,斷路器炬灭,智...
    卡卡羅2017閱讀 134,637評論 18 139
  • 文/行路人 一個有態(tài)度的極客@靠譜的投資人 言有物,行有格靡菇。行路人踐行:行文開宗明義重归、言簡意賅,出處嚴謹厦凤。本文講的...
    大唐陳校長閱讀 1,492評論 6 12
  • 我想過無數(shù)次较鼓,我們相遇的方式椎木, 有歡喜的违柏,也有悲傷的 可偏偏為什么會是這一種。 01你剛好成熟香椎,我剛好溫柔 我們相...
    云蒹閱讀 748評論 1 2