url scheme系列二----不使用SDK自己完成分享

既然知道了我们可以自己构造scheme url打开其他App,并完成对应的业务操作。那么我们来试试,不适用SDK的情况下,完成分享信息到QQ和QZone.

首先,假设我们做成一个标准,任何遵循我们这个标准都可以被我们直接拿来使用,将数据分享到对应的平台。Ok,我们先定义一个分享的标准Api接口。

/**
 *  所有分享平台必须实现的规范
 */
@protocol ShareInterface <NSObject>

@required

//分享平台的关键字
- (NSString *)platformName;

//分享平台的类型
- (XZHSharePlatform)platformType;

//secret是可选
- (void)registWithAppIdOrAppKey:(NSString *)keyOrId
                      AppSecret:(NSString *)secret;

//分享
- (void)startShare:(XZHMessage *)message Type:(XZHShareType)shareType;

- (BOOL)handleOpenURL;

@optional

//授权
- (void)oauth;

- (BOOL)isInstalled;

@end

定义完接口后,我们开始做一个分享到腾讯平台的接口实现。

//.h

#import <Foundation/Foundation.h>
#import "XZHShareBase.h"

//注: XZHShareBase类默认实现了接口,并提供了一些基础代码
@interface XZHShareToQQ : XZHShareBase 

@end
//.m
- (NSString *)platformName {
    return @"QQ";
}

- (XZHSharePlatform)platformType {
    return XZHShareQQ;
}
/**
 *    把传入的appKey和appSecret使用单例对象保存起来,方便后面使用
 */
- (void)registWithAppIdOrAppKey:(NSString *)keyOrId AppSecret:(NSString *)secret {
    //保存参数
    NSDictionary *options = @{
                              @"appid" : keyOrId,
                              @"callback_name" : [NSString stringWithFormat:@"QQ%02llx",[keyOrId longLongValue]]
                              };

    [self saveOptions:options];
}
/**
 *    分享信息的核心方法:
 *        1. 根据不同的分享Api,构造不同的scheme url
 *        2. 构造完scheme url后,openURL打开url,掉起QQ
 */

- (void)startShare:(XZHMessage *)message Type:(XZHShareType)shareType
{
    NSString *url = @"";

    if (shareType == XZHShareToQZone) {
        url = [self _genShareUrl:message to:XZHTencentQZone];
    } else if (shareType == XZHShareToQQFriend) {
        url = [self _genShareUrl:message to:XZHTencentMobileQQ];
    } else if (shareType == XZHShareToQQFavirate) {
        url = [self _genShareUrl:message to:XZHTencentQQShareFavorites];
    } else if (shareType == XZHShareToQQDataLine) {
        url = [self _genShareUrl:message to:XZHTencentQQShareDataline];
    }

    [[self class] openURL:url];
}    
/**
 *  根据不同分享Api,生成不同的分享schme url
 */
- (NSString*)_genShareUrl:(XZHMessage *)msg to:(XZHTencentPlatform)shareTo {

    NSString *url = [[NSString alloc] initWithString:ShareSchema];

    NSString *boundleName = [XZHShareManager base64Encode:[XZHShareManager CFBundleDisplayName]];
    NSString *callback_name = [[self optionDict] objectForKey:@"callback_name"];

    NSMutableDictionary *params = [@{
                                    @"thirdAppDisplayName" : boundleName,
                                    @"version" : @"1",
                                    @"cflag" : [NSString stringWithFormat:@"%ld", shareTo],
                                    @"callback_type" : @"scheme",
                                    @"generalpastboard" : @"1",
                                    @"callback_name" : callback_name,
                                    @"src_type" : @"app",
                                    @"shareType" : @"0",
                                    } mutableCopy];

    //如果未给当前message对象设置 分享消息类型,则默认为 news类型
    if (msg.link && !msg.messageType) {
        msg.messageType = XZHMessageNews;
    }

    NSDictionary *subParams = nil;

    if ([msg computeMessageType] == XZHMessageText) {

        NSString *fileData = [XZHShareManager base64AndUrlEncode:msg.title];
        subParams = @{
                      @"file_type" : @"text",
                      @"file_data" : fileData
                      };

    } else if ([msg computeMessageType] == XZHMessageImage) {

        //将message保存到剪贴板
        NSDictionary *data=@{
                             @"file_data":msg.imageData,
                             @"previewimagedata":msg.thumbImageData?:msg.imageData
                             };

        [[XZHShareManager manager] clipBoardSave:data
                                          ForKey:SaveObjectForQQPlatformKey
                                        Encoding:XZHClipBoardNSKeyedArchiver];

        NSString *title = [XZHShareManager base64AndUrlEncode:msg.title];
        NSString *desc = [XZHShareManager base64AndUrlEncode:msg.desc];
        subParams = @{
                      @"file_type" : @"img",
                      @"title" : title,
                      @"objectlocation" : @"pasteboard",
                      @"description" : desc,
                      };

    }else if ([msg computeMessageType] == XZHMessageNews) {

        NSDictionary *[email protected]{@"previewimagedata":msg.imageData};

        //图片保存到剪贴板
        [[XZHShareManager manager] clipBoardSave:data
                                          ForKey:SaveObjectForQQPlatformKey
                                        Encoding:XZHClipBoardNSKeyedArchiver];

        NSString *title = [XZHShareManager base64AndUrlEncode:msg.title];
        NSString *url = [XZHShareManager base64AndUrlEncode:msg.link];
        NSString *desc = [XZHShareManager base64AndUrlEncode:msg.desc];

        NSString *msgType=@"news";
        if (msg.messageType == XZHMessageNews) {
            msgType = @"news";
        } else if (msg.messageType == XZHMessageAudio) {
            msgType = @"audio";
        }

        subParams = @{
                      @"file_type" : msgType,
                      @"title" : title,
                      @"url" : url,
                      @"description" : desc,
                      @"objectlocation" : @"pasteboard",
                      };
    }

    //得到最后字典
    [params addEntriesFromDictionary:subParams];

    //构造最后的scheme url
    url = [XZHShareManager urlStringWithOriginUrlString:url appendParameters:params];

    return url;
}
//QQ处理完毕后,回调我们的App,执行Appdelegate回调函数

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

    //其他应用掉起当前应用时,传回的参数,如果传入的url能够处理
    if ([[XZHShareManager manager] handleOpenURL:url]) {
        return YES;
    }

    //不能处理的App调起
    return YES;
}
//XZHShareManager.m 所有我们管理的分享平台的回调函数,统一有这个类来分发,轮训所有的分享平台,看哪个能处理

- (BOOL)handleOpenURL:(NSURL *)url {
    self.returnURL = url;

    //轮训所有分享平台,看哪个能处理
    for (id<XZHShareInterface> impl in self.platforms) {
        if ([impl handleOpenURL]) {
            return YES;
        }
    }
    return NO;
}
//ShareToQQ.m 处理App回调时,QQ回传的参数

- (BOOL)handleOpenURL {
    XZHShareManager *manager = [XZHShareManager manager];
    NSString *returnURL = [manager.returnURL absoluteString];

    if ([returnURL hasPrefix:ShareCallbackSchemePrix]) {
        NSDictionary *dict = [XZHShareManager parseUrl:[XZHShareManager manager].returnURL];
        if ([dict hasKey:@"error_description"]) {
            [dict setValue:[XZHShareManager base64Decode:dict[@"error_description"]] forKey:@"error_description"];
        }
        if ([dict hasKey:@"error"]) {
            NSInteger code = [dict[@"error"] integerValue];
            if (code != 0) {
                NSError *error = [NSError errorWithDomain:@"response_from_qq" code:code userInfo:dict];
                if (manager.onShareFail) {
                    manager.onShareFail(manager.shareMessage, error);
                }
            }else {
                if (manager.onShareSuccess) {
                    manager.onShareSuccess(manager.shareMessage);
                }
            }
        }

        [manager clearCompletions];

        return YES;
    } else if ([returnURL hasPrefix:OauthCallbackSchemePrix]) {

        return YES;
    } else {
        return NO;
    }
}
时间: 2024-10-30 21:44:05

url scheme系列二----不使用SDK自己完成分享的相关文章

url scheme系列一----基本使用

url scheme是什么,能做什么? url cheme,用于两个独立的App之间,让A应用能够打开B应用 A应用打开B应用时,告诉B应用当前这个传入的scheme要干什么,所需要的参数 URL Schemes 是一个数组,允许应用定义多个 URL schemes ,每一个scheme对应不同的业务操作 url scheme操作步骤一.根据要调用的App规定的scheme和参数格式进行拼接,最终打开的url /** * 生成完整的 scheme url */ - (NSString*)_gen

iOS不同应用切换中URL Scheme的使用介绍

URL Scheme是iOS SDK提供给开发者的通过URL打开系统或第三方应用的方式,iOS开发中常见的几种需求,比如分享到微信微博,或调用支付宝支付之类的调用其他应用,以及调用完后,第三方应用对自己的回调都需要用到URL Scheme的知识,关于URL Scheme有这么几点需要了解 一.怎么通过一个应用的URL Scheme打开对应应用的对应页面 从一个应用切换到另一个应用所调用的关键方法是UIApplication的单例方法openURL: UIApplication.sharedApp

Cordova Android源码分析系列二(CordovaWebView相关类分析)

本篇文章是Cordova Android源码分析系列文章的第二篇,主要分析CordovaWebView和CordovaWebViewClient类,通过分析代码可以知道Web网页加载的过程,错误出来,多线程处理等. CordovaWebView类分析 CordovaWebView类继承了Android WebView类,这是一个很自然的实现,共1000多行代码.包含了PluginManager pluginManager,BroadcastReceiver receiver,CordovaInt

使用 PySide2 开发 Maya 插件系列二:继承 uic 转换出来的 py 文件中的类 Ui_Form

使用 PySide2 开发 Maya 插件系列二:继承 uic 转换出来的 py 文件中的类 Ui_Form 开发环境: Wing IDE 6.1 步骤1: 打开 Wing IDE,创建一个新的 project,保存这个 project 到某个路径下,把之前生产的 py 文件所在的文件夹添加到该 project 中,然后在文件夹下新建一个 py 文件,我这里命名为 PySideTest.py 图中 PySide2ToPySide.py 是一个 PySide2 兼容 PySide 的一个补丁代码,

(已解决)#warning:尚未配置[微信]URL Scheme:wx4868b35061f87884, 无法使用进行授权。

#warning:尚未配置[微信]URL Scheme:wx4868b35061f87884, 无法使用进行授权. (说白了就是注册白名单) " -canOpenURL: failed for URL: "weixin://app/wx4868b35061f87885/" - error: "This app is not allowed to query for scheme weixin"  " 此error源自iOS9 URL Scheme

Maven入门系列(二)--设置中央仓库的方法

原文地址:http://www.codeweblog.com/maven入门系列-二-设置中央仓库的方法/ Maven仓库放在我的文档里好吗?当然不好,重装一次电脑,意味着一切jar都要重新下载和发布. 下载的地址是中央仓库mvnrepository.com,当然,全球很多个仓库. 资源的坐标简称GVA 那么,现在如何修改maven的本地仓库路径呢? 关键在于maven文件夹的config下的settings.xml(E:\IDE\apache-maven-3.3.1\conf\settings

Maven 系列 二 :Maven 常用命令,手动创建第一个 Maven 项目

1.根据 Maven 的约定,我们在D盘根目录手动创建如下目录及文件结构: 2.打开 pom.xml 文件,添加如下内容: 1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

Maven 系列 二 :Maven 常用命令,手动创建第一个 Maven 项目【转】

1.根据 Maven 的约定,我们在D盘根目录手动创建如下目录及文件结构: 2.打开 pom.xml 文件,添加如下内容: 1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

WPF入门教程系列二——Application介绍

原文:WPF入门教程系列二--Application介绍 一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只有一个 Application 实例存在.和 WinForm 不同的是WPF Application默认由两部分组成 : App.xaml 和 App.xaml.cs,这有点类似于 Asp.Net WebForm,将定义和行为代码相分离. 微