Swift - 发送消息(文本,图片,文件等)给微信好友或分享到朋友圈
通过调用微信提供的API接口,我们可以很方便的在应用中发送消息给微信好友,或者分享到朋友圈。在微信开发平台(https://open.weixin.qq.com)里,提供了详细的说明文档和样例。但由于提供的样例是使用Objective-C写的,所以这边我写了个Swift版的样例。
(3)导入有关的类库:
1,实现的功能
(1)可以发送各种类型的消息给好友,也可以分享到朋友圈
(2)发送的内容类型包括:纯文本,图片,链接,音乐,视频,gif表情,非gif表情,文件
2,效果图如下
3,注意事项:
(1)该样例必须连接手机进行真机调试
(2)还需要到微信开发平台注册应用id,下面代码里会用到(如果不注册,随便起个id来调试也没什么问题,就是收到消息下方会显示“未审核应用”,同时发送完毕以后程序这边接收不到回调响应。现在微信策略调整,必须使用注册的AppID才可以发送消息。否则会报“由于bad_param,无法分享到微信”错误。)
4,详细步骤
(1)首先把微信SDK资源库拖入到项目中来(整个SDK文件夹)
(2)建立桥接文件bridge.h,并引入
#import "WechatAuthSDK.h" #import "WXApi.h" #import "WXApiObject.h"
CoreTelephony.framework,SystemConfiguration.framework,libc++.tbd,libz.tbd,libsqlite3.0.tbd。
--- AppDelegate.swift ---
5,源码下载:
(4)自iOS 9起,系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单。
在“Info.plist”里增加如下代码:
(5)在 “info” -> “URL Types”中,新增一个 URL Schemes。新的 Schemes 命名是便是你注册的 AppID。(URL Schemes 的配置是为了让你跳转到微信发送消息后,还能跳回原来的App上。)
<key>LSApplicationQueriesSchemes</key> <array> <string>weixin</string> </array> <key>LSRequiresIPhoneOS</key> <true/> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
(5)在 “info” -> “URL Types”中,新增一个 URL Schemes。新的 Schemes 命名是便是你注册的 AppID。(URL Schemes 的配置是为了让你跳转到微信发送消息后,还能跳回原来的App上。)
(6)编写代码
--- AppDelegate.swift ---
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // 注册app WXApi.registerApp("wxe569f3b201ff5573") return true } //重写openURL func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { return WXApi.handleOpen(url, delegate: self) } //微信分享完毕后的回调(只有使用真实的AppID才能收到响应) func onResp(_ resp: BaseResp!) { if resp.isKind(of: SendMessageToWXResp.self) {//确保是对我们分享操作的回调 if resp.errCode == WXSuccess.rawValue{//分享成功 print("分享成功") }else if resp.errCode == WXErrCodeCommon.rawValue {//普通错误类型 print("分享失败:普通错误类型") }else if resp.errCode == WXErrCodeUserCancel.rawValue {//用户点击取消并返回 print("分享失败:用户点击取消并返回") }else if resp.errCode == WXErrCodeSentFail.rawValue {//发送失败 print("分享失败:发送失败") }else if resp.errCode == WXErrCodeAuthDeny.rawValue {//授权失败 print("分享失败:授权失败") }else if resp.errCode == WXErrCodeUnsupport.rawValue {//微信不支持 print("分享失败:微信不支持") } } } func applicationWillResignActive(_ application: UIApplication) { } func applicationDidEnterBackground(_ application: UIApplication) { } func applicationWillEnterForeground(_ application: UIApplication) { } func applicationDidBecomeActive(_ application: UIApplication) { } func applicationWillTerminate(_ application: UIApplication) { } }--- ViewController.swift ---
import UIKit class ViewController: UIViewController { //发送给好友还是朋友圈(默认好友) var _scene = Int32(WXSceneSession.rawValue) override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } //切换发送给好友还是朋友圈 @IBAction func changeScene(_ sender: UISegmentedControl) { if sender.selectedSegmentIndex == 0 { _scene = Int32(WXSceneSession.rawValue) }else{ _scene = Int32(WXSceneTimeline.rawValue) } } //发送纯文本 @IBAction func sendTextContent(_ sender: AnyObject) { let req = SendMessageToWXReq() req.bText = true req.text = "hangge.com 做最好的开发者知识平台。" req.scene = _scene WXApi.send(req) } //发送图片 @IBAction func sendImageContent(_ sender: AnyObject) { let message = WXMediaMessage() //发送的图片 let filePath = Bundle.main.path(forResource: "image", ofType: "jpg") let image = UIImage(contentsOfFile:filePath!) let imageObject = WXImageObject() imageObject.imageData = UIImagePNGRepresentation(image!) message.mediaObject = imageObject //图片缩略图 let width = 240.0 as CGFloat let height = width*image!.size.height/image!.size.width UIGraphicsBeginImageContext(CGSize(width: width, height: height)) image!.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) message.setThumbImage(UIGraphicsGetImageFromCurrentImageContext()) UIGraphicsEndImageContext() let req = SendMessageToWXReq() req.bText = false req.message = message req.scene = _scene WXApi.send(req) } //发送链接 @IBAction func sendLinkContent(_ sender: AnyObject) { let message = WXMediaMessage() message.title = "欢迎访问 hangge.com" message.description = "做最好的开发者知识平台。分享各种编程开发经验。" message.setThumbImage(UIImage(named:"apple.png")) let ext = WXWebpageObject() ext.webpageUrl = "http://hangge.com" message.mediaObject = ext let req = SendMessageToWXReq() req.bText = false req.message = message req.scene = _scene WXApi.send(req) } //发送音乐 @IBAction func sendMusicContent(_ sender: AnyObject) { let message = WXMediaMessage() message.title = "一无所有" message.description = "崔健" message.setThumbImage(UIImage(named:"apple.png")) let ext = WXMusicObject() ext.musicUrl = "http://y.qq.com/portal/song/103347_num.html" ext.musicDataUrl = "http://stream20.qqmusic.qq.com/32464723.mp3" message.mediaObject = ext let req = SendMessageToWXReq() req.bText = false req.message = message req.scene = _scene WXApi.send(req) } //发送视频 @IBAction func sendVideoContent(_ sender: AnyObject) { let message = WXMediaMessage() message.title = "乔布斯访谈" message.description = "饿着肚皮,傻逼着。" message.setThumbImage(UIImage(named:"apple.png")) let ext = WXVideoObject() ext.videoUrl = "http://v.youku.com/v_show/id_XNTUxNDY1NDY4.html" message.mediaObject = ext let req = SendMessageToWXReq() req.bText = false req.message = message req.scene = _scene WXApi.send(req) } //发送非gif格式的表情 @IBAction func sendNonGifContent(_ sender: AnyObject) { let message = WXMediaMessage() message.setThumbImage(UIImage(named:"res5thumb.png")) let ext = WXEmoticonObject() let filePath = Bundle.main.path(forResource: "res5", ofType: "jpg") let url = URL(fileURLWithPath: filePath!) ext.emoticonData = try! Data(contentsOf: url) message.mediaObject = ext let req = SendMessageToWXReq() req.bText = false req.message = message req.scene = _scene WXApi.send(req) } //发送gif格式的表情 @IBAction func sendGifContent(_ sender: AnyObject) { let message = WXMediaMessage() message.setThumbImage(UIImage(named:"res6thumb.png")) let ext = WXEmoticonObject() let filePath = Bundle.main.path(forResource: "res6", ofType: "gif") let url = URL(fileURLWithPath: filePath!) ext.emoticonData = try! Data(contentsOf: url) message.mediaObject = ext let req = SendMessageToWXReq() req.bText = false req.message = message req.scene = _scene WXApi.send(req) } //发送文件 @IBAction func sendFileContent(_ sender: AnyObject) { let message = WXMediaMessage() message.title = "ML.pdf" message.description = "Pro CoreData" message.setThumbImage(UIImage(named:"apple.png")) let ext = WXFileObject() ext.fileExtension = "pdf" let filePath = Bundle.main.path(forResource: "ML", ofType: "pdf") let url = URL(fileURLWithPath: filePath!) ext.fileData = try! Data(contentsOf: url) message.mediaObject = ext let req = SendMessageToWXReq() req.bText = false req.message = message req.scene = _scene WXApi.send(req) } }
5,源码下载:
WeiXinShare.zip (2015-06-09)
WeiXinShare2.zip (2015-12-11)
WeiXinShare2.zip (2016-07-30 )
WeiXinShare2.zip (2016-08-17 Swift2)
hangge_757.zip(2016-09-22 最新版 Swift3)
您好 我是一名学生正在学习iOS开发写App。我申请微信开放平台的AppID失败了,因为没有对应的应用官网。但是作为学生也确实没有啊哭泣T_T 那请问非官方正式的开发者如何申请呢?请问站长有什么建议吗?谢谢。
撸主帮了我大忙了,傻逼微信报个什么 bad_param 错误,就不能直接说 appId 不对?浪费我时间
分享成功之后回跳到APP之后不会触发onResp方法,用站长提供的demo也是一样。可以正常分享,正常的返回,就是不会执行回调方法。
能把这个App发我邮箱吗
您好,我子啊APPDELEGATE里面毁掉方法都设置了,但是在分享完成以后点击返回我的APP,没有反应,还是留在微信界面,请问什么原因
站长,还有个问题:如果我们这android这里申请到了app ID之后,我可以共用吗
还有qq的app ID ,因为我没有申请,所以问一下可以和android共用一个吗
站长,如果像天气通一样直接把整个滚动视图截下来分享到好友朋友圈的,该怎么弄呢?
我的想法是先截屏,然后保存到相册,用您这篇文章里分享图片的方法实现
但是问题就是截屏保存本地相册的时候,不知道怎么命名,就导致分享图片的时候不知道截的图叫什么,求解
bad_param 无法分享到微信是什么原因啊
发送链接. 如何发送分享页面链接呢 URL schemes 如何设置?
你好,我想请问一下,我在建立Coredata的时候已经有个桥头文件,现在这个桥头文件该写在哪里呢。
发现一个新的问题,分享下,我下载了您的附件,在WXSDK目录下WXApiObject.h,和我在官网下载的最新的wxsdk的WXApiObject对比了一下,其中WXScene一个枚举多了值。
这是您的:
enum WXScene {
WXSceneDefault = -1,
WXSceneSession = 0,
WXSceneTimeline = 1,
WXSceneFavorite = 2,
};
这是我在官网下载最新的sdk:
enum WXScene {
WXSceneSession = 0, /**< 聊天界面 */
WXSceneTimeline = 1, /**< 朋友圈 */
WXSceneFavorite = 2, /**< 收藏 */
};
现在的问题是,前面我使用rawValue来获取枚举的值,其类型是UInt32,而Req里scene的类型是Int32类型,req.scene = Int32(_scene) ,必须这样才可以编译通过。
OK,我已经找到原因了,将value改成rawValue就可以常编译了。
多谢楼主分享技术,在var _scene = WXSceneSession.value 这里,显示WXSceneSession没有value这个成员,我的sdk已正确引入。
这个例子可以增加一个回调
我写好了。友盟集成的。挺简单的。。网站不能注册?自己发文章么。。
请问撸主做过swift对友盟的集成啊。
撸主可以写一个。swift 对接友盟的啊。
撸主有swift微信支付的示例吗,遍寻网上没找一个合适的 。。。求一个微信支付的。。
附件上传到github就好了