• 主页
  • 随笔
  • 技术笔记
  • 全部文章
标签 友链 关于我

  • 主页
  • 随笔
  • 技术笔记
  • 全部文章

MonkeyKing:无需集成第三方直接分享登录

阅读数:次 2018-09-18
字数统计: 2.1k字   |   阅读时长≈ 9分

MonkeyKing:无需集成第三方直接分享登录

集成第三方的东西虽然很简单,但是如果出现了一些编译上的错误,作为菜鸟是很难处理的。而最简单有效的处理方式就是把第三方的SDK全部移除再重新添加,错误就神奇的消失啦~

之前公司技术总监因故放弃了使用友M去管理第三方SDK,采取直接去第三方平台下载SDK集成的方式,导致项目里的SDK管理混乱。那么可不可以不使用第三方的SDK来实现第三方平台的分享、授权、支付等操作嘞?那就请猴王MonkeyKing来收服这些SDK吧~
其实官方demo里面的例子讲的很清楚了,但是自己动手按照自己喜欢的方式封装一下内部方法,用起来也舒服些~
正片

操作环境:

  1. xcode 8.2.1
  2. swift 3.0
  3. 准备工作

新建一个xcode项目,使用CocoaPods导入MonkeyKing。

    platform :ios, '9.0'
    target 'MonkeyKingDemo' do
      # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
      use_frameworks!
      pod 'MonkeyKing'
    end
    

先从第三方分享开始吧~
打开项目,先根据自己的需求配置一下第三方平台的URL Type(微信,qq,微博等等)。

avatar

avatar

我们创建一个工具类thirdParty.swift来统一管理第三方的业务逻辑。

先按照自己的需求,定义一些枚举方便使用。

    // 分享类型
    enum shareType {
        case weChatSession
        case weChatTimeline
        case weibo
        case qqFriend
        case qqZone
        case other // 占位用
    }
    // 第三方平台类型
    enum platformType {
        case weChat
        case qq
        case weibo
        case alipay
        case other //占位用
    }

我们给工具类定义一个注册第三方账号的类方法,这个方法我们可以在app启动时就调用,或者在你需要使用第三方之前调用。第三方的App key 和App ID、回调地址,我们可以在该工具类里面定义一些常量来管理,这里不再赘述。

    /// regist third account
        class func registAccount() {
            MonkeyKing.registerAccount(.weChat(appID: "xxxxxxx", appKey: "xxxxxxx"))
            MonkeyKing.registerAccount(.weibo(appID: "xxxxxxx", appKey: "xxxxxxx", redirectURL: "xxxxxxx"))
            MonkeyKing.registerAccount(.qq(appID: "xxxxxxx"))
        }

通常我们就在app刚启动时调用这个方法吧~

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            // regist third account
            thirdParty.registAccount()
            return true
        }

如果我们还需要处理第三方的回调,那么我们还需要在AppDelegate里面添加以下处理。

    // iOS 10
    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
            _ = MonkeyKing.handleOpenURL(url)
            return true
     }
    // iOS 9
    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
            _ = MonkeyKing.handleOpenURL(url)
            return true
    }
    

是不是已经等不及了

第三方分享

同常我们需要分享的内容包括文字、图片、链接、视频、音频。在这里我只是把常用的文字、图片、链接分享处理一下,音视频一般不太用的到,如果需要的话,大同小异。

首先我们在thirdParty里面增加一个内部使用的方法,实际上就是封装了MonkeyKing的内部方法,方便我们使用。分享文字、图片和链接时所封装的方法内部都会用到这个方法,不需要暴露给外界,所以方法加了fileprivate关键字

    fileprivate class func shareInfo(_ info: MonkeyKing.Info, shareType: shareType) {
            var message: MonkeyKing.Message?
            switch shareType {
            case .weChatSession:
                message = MonkeyKing.Message.weChat(.session(info: info))
            case .weChatTimeline:
                message = MonkeyKing.Message.weChat(.timeline(info: info))
            case .weibo:
                message = MonkeyKing.Message.weibo(.default(info: info, accessToken: nil))
            case .qqFriend:
                message = MonkeyKing.Message.qq(.friends(info: info))
            case .qqZone:
                message = MonkeyKing.Message.qq(.zone(info: info))
            default:
                break
            }
            // 处理分享结果
            if let message = message{
                MonkeyKing.deliver(message) { result in
                    print("result: \(result)")
                }
            }
        }

分享文字

分享文字的话,其实方法参数里只留下text就可以,博主因为强迫症,各个方法都想要长得一样。。。所以用不到的参数也加上了。。。额。。。

    class func share(text: String?, title: String?, description: String?, shareType: shareType) {
            guard let text = text else { return }
            let info = MonkeyKing.Info(
                title: text,
                description: nil,
                thumbnail: nil,
                media: nil
            )
            shareInfo(info, shareType: shareType)
        }

分享图片

分享图片的话有一点是需要注意的。第三方对图片的缩略图大小是有限制的,通常是不能大于32kb(32768b),所以需要对传入的待分享图片的缩略图进行处理。
我们先增加一个UIImage类的扩展,用于压缩图片体积,备用。这个方法比较简单粗暴,如果有更科学的方法,大家请分享一下。

    extension UIImage {
        /// 压缩图片大小
        ///
        /// - Parameters:
        ///   - maxLength: 最大尺寸(比特)
        ///   - compress: 压缩系数(0~1)
        /// - Returns:
        func compress(maxLength: Int, compress: CGFloat = 0.90) -> Data? {
            let data = UIImageJPEGRepresentation(self, compress)
            if (data?.count)! < maxLength || compress < 0{
                return data
            }
            return self.compress(maxLength: maxLength, compress: compress-0.05)
        }
    }

然后我们依旧在thirdParty里面增加一个内部使用的方法,来压缩图片缩略图。这里的3000是指32kb(32768b),博主强迫症,非得弄个整数不可。

    fileprivate class func compress(thumbnail: UIImage) -> UIImage? {
            if let data = UIImageJPEGRepresentation(thumbnail, 1) {
                if data.count < 30000 { return thumbnail } // 无需压缩
            }
            if let imageData = thumbnail.compress(maxLength: 30000) {
                if imageData.count > 30000 { // 还不符合尺寸要求?再压
                    if let compressedImage = UIImage(data: imageData) {
                        return compress(thumbnail: compressedImage)
                    }
                } else {
                    if let compressedImage = UIImage(data: imageData) {
                        return compressedImage
                    }
                }
            }
            return nil
        }

最后,我们进行图片分享

    class func share(image: UIImage?, thumbnail: UIImage?, shareType: shareType) {
            guard let image = image else { return }
            var compressedThumbnail: UIImage?
            if thumbnail != nil { // 如果传入了缩略图,也得判断一下尺寸是否合格
                if let compressedImage = compress(thumbnail: thumbnail!) {
                    compressedThumbnail = compressedImage
                }
            } else { // 没有缩略图,那就取原图来压一个缩略图来用
                if let compressedImage = compress(thumbnail: image) {
                    compressedThumbnail = compressedImage
                }
            }
            let info = MonkeyKing.Info(
                title: nil,
                description: nil,
                thumbnail: compressedThumbnail,
                media: .image(image)
            )
            shareInfo(info, shareType: shareType)
        }

分享链接

如果分享的链接需要配缩略图,缩略图也要符合尺寸的要求。

    class func share(url: String?, thumbnail: UIImage?, title: String?, description: String?, shareType: shareType) {
            guard let urlString = url else { return }
            guard let url = URL(string: urlString) else { return }
            
            var compressedThumbnail: UIImage?
            if thumbnail != nil {
                if let compressedImage = compress(thumbnail: thumbnail!) {
                    compressedThumbnail = compressedImage
                }
            }
        
            let info = MonkeyKing.Info(
                title: title,
                description: description,
                thumbnail: compressedThumbnail,
                media: .url(url)
            )
            shareInfo(info, shareType: shareType)
        }

呐,是不是很简单

第三方授权

我们先在thirdParty里定义一个闭包来处理第三方授权后返回的数据。

    public typealias completionHandler = (_ info: [String: Any]?, _ response: URLResponse?, _ error: Error?) -> Void

然后。。。就用这个方法。

      // MARK:-OAuth
    class func OAuth(platformType: platformType, completionHandler: @escaping completionHandler) {
            switch platformType {
            case .weChat:
                MonkeyKing.oauth(for: .weChat) { (info, response, error) in
                    completionHandler(info, response, error)
                }
            case .qq:
                MonkeyKing.oauth(for: .qq, scope: "get_user_info") { (info, response, error) in
                    completionHandler(info, response, error)   
                }
            case .weibo:
                MonkeyKing.oauth(for: .weibo) { (info, response, error) in
                    completionHandler(info, response, error)
                }
            default:
                break
            }
            
        }

在我们需要第三方授权的地方使用这个方法,并在回调里处理返回的数据。
例如微信:

    thirdParty.OAuth(platformType: .weChat) { (dictionary, response, error) in
                print("dictionary \(dictionary)")
                print("error \(error)")
    }

第三方支付

关于支付这个地方,其实demo不太好处理。但是我依然稍微封了一个方法,就待优化吧。
我们先在thirdParty里定义一个闭包来处理第三方支付后返回的数据。

    public typealias payCompletionHandler = (_ result: Bool) -> Void

然后。。。就用这个方法。传入的urlString是发起订单后server端返回的数据拼接出来的,这一点还是不太方便的。例如微信的订单(此处WXPayModel是用户根据后台返回数据自己定义的):

     let string = "weixin://app/\(WXPayModel.appid!)/pay/?nonceStr=\(WXPayModel.noncestr!)&package=Sign%3DWXPay&partnerId=\(WXPayModel.partnerid!)&prepayId=\(WXPayModel.prepayid!)&timeStamp=\(UInt32(WXPayModel.timestamp!))&sign=\(WXPayModel.sign!)&signType=SHA1"
    获取到订单信息后拼接为url,作为参数传入以下方法。
    
    // MARK:-Pay
    class func pay(platformType: platformType, urlString: String, completionHandler: @escaping payCompletionHandler) {
            switch platformType {
            case .weChat:
                let order = MonkeyKing.Order.weChat(urlString: urlString)
                MonkeyKing.deliver(order) { result in
                    completionHandler(result)
                }
            case .alipay:
                let order = MonkeyKing.Order.alipay(urlString: urlString)
                MonkeyKing.deliver(order) { result in
                    completionHandler(result)
                }
            default:
                break
            }
      }

结束语

更详细的使用,请大家移步至MonkeyKing下载官方的demo来学习吧~
MonkeyKing由国人开发,目前由四个大牛程序员维护。不引入SDK,方便快捷,减少项目体积,大家有兴趣可以试试~
我的demo地址demo,因为分享、授权、支付等应用场景很多,所以demo里面并没有一一实现,仅仅提供该thridParty工具类以及相关类扩展。有什么疑问或建议,请留言~

avatar

  • 本文作者: Grx
  • 本文链接: https://ruixiaoguo.github.io/Grx.github.io/Grx.github.io/2018/09/18/MonkeyKing:无需集成第三方直接分享登录/
  • 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!
  • MonkeyKing

扫一扫,分享到微信

LLDebugTool - 便捷的IOS调试工具(支持Swift)
流言终结者- Flutter和RN谁才是更好的跨端开发方案?
  1. 1. MonkeyKing:无需集成第三方直接分享登录
    1. 1.1. 新建一个xcode项目,使用CocoaPods导入MonkeyKing。
    2. 1.2. 第三方分享
    3. 1.3. 分享文字
    4. 1.4. 分享图片
    5. 1.5. 分享链接
    6. 1.6. 第三方授权
    7. 1.7. 第三方支付
© 2014-2024 Grx
GitHub:hexo-theme-yilia-plus by Litten
本站总访问量次 | 本站访客数人
  • 标签
  • 友链
  • 关于我

tag:

  • life
  • OC
  • Google
  • Fastlane
  • Flutter
  • hexo
  • 智能家居
  • Apple Watch
  • 逆向
  • Lottie
  • PHP
  • cocos2d
  • Mac
  • MonkeyKing
  • RN
  • Swift
  • RAC
  • WKWebView
  • WebView
  • Xcode
  • xcode
  • ios
  • Android
  • appledoc
  • MMKV
  • LLVM
  • FreamWork






    
    

  • 唐巧的博客
  • 王巍(喵神)OneVsDen
  • 阿里“念纪“
  • 滴滴-戴铭
  • 郭曜源(ibireme)
  • 阿里”南栀倾寒“
  • 蘑菇街李忠
  • 码农人生
  • 玉令天下
  • bang
  • Ian的博客
这里是Grx的个人博客:
iOS开发工程师一枚
联系方式:
QQ:1217255509
Email:grx0917@sina.com
知识管理,时间管理,自我管理,架构即未来
欢迎技术交流!