XYSocialShareHandler.m 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. //
  2. // XYSocialShareHandler.m
  3. // Starbuds
  4. //
  5. // Created by 翟玉磊 on 2020/1/19.
  6. // Copyright © 2020 翟玉磊. All rights reserved.
  7. //
  8. #import "XYSocialShareHandler.h"
  9. #import "WXApi.h"
  10. #import "WeiboSDK.h"
  11. @interface XYSocialShareHandler ()<WBHttpRequestDelegate, WBMediaTransferProtocol>
  12. @end
  13. @implementation XYSocialShareHandler
  14. + (instancetype)sharedInstance {
  15. static XYSocialShareHandler *shareManager;
  16. static dispatch_once_t onceToken;
  17. dispatch_once(&onceToken, ^{
  18. shareManager = [[XYSocialShareHandler alloc] init];
  19. });
  20. return shareManager;
  21. }
  22. - (instancetype)init {
  23. if (self = [super init]) {
  24. }
  25. return self;
  26. }
  27. /**
  28. 分享给微信好友图片
  29. @param image 原图
  30. @param thumImage 缩略图
  31. */
  32. - (void)share_WXImageWithImage:(UIImage *)image thumbImage:(UIImage *)thumImage {
  33. /// 大小不能超过64K
  34. UIImage *thumbUrlImage = [UIImage imageWithMaxSide:100.0f sourceImage:image];
  35. WXMediaMessage *message = [WXMediaMessage message];
  36. [message setThumbImage:thumbUrlImage];
  37. WXImageObject *imageObject = [WXImageObject object];
  38. imageObject.imageData = UIImageJPEGRepresentation(image, 1);
  39. message.mediaObject = imageObject;
  40. SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
  41. req.bText = NO;
  42. req.message = message;
  43. req.scene = WXSceneSession; //分享到微信好友
  44. [WXApi sendReq:req completion:nil];
  45. }
  46. /**
  47. 分享给微信朋友圈图片
  48. @param image 原图
  49. @param thumImage 缩略图
  50. */
  51. - (void)share_PYQImageWithImage:(UIImage *)image thumbImage:(UIImage *)thumImage {
  52. /// 大小不能超过64K
  53. UIImage *thumbUrlImage = [UIImage imageWithMaxSide:100.0f sourceImage:image];
  54. WXMediaMessage *message = [WXMediaMessage message];
  55. [message setThumbImage:thumbUrlImage];
  56. WXImageObject *imageObject = [WXImageObject object];
  57. imageObject.imageData = UIImageJPEGRepresentation(image, 1);
  58. message.mediaObject = imageObject;
  59. SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
  60. req.bText = NO;
  61. req.message = message;
  62. req.scene = WXSceneTimeline; //分享到微信朋友圈
  63. [WXApi sendReq:req completion:nil];
  64. }
  65. /**
  66. 分享给微信好友链接
  67. @param title 标题
  68. @param description 描述
  69. @param image 缩略图
  70. @param url url
  71. */
  72. - (void)share_WXURLWithTitle:(NSString *)title description:(NSString *)description thumbImage:(UIImage *)image url:(NSString *)url {
  73. /// 大小不能超过64K
  74. UIImage *thumbUrlImage = [UIImage imageWithMaxSide:80.0f sourceImage:image];
  75. WXMediaMessage *message = [WXMediaMessage message];
  76. message.title = title;
  77. message.description = description;
  78. [message setThumbImage:thumbUrlImage];
  79. WXWebpageObject *webpageObject = [WXWebpageObject object];
  80. webpageObject.webpageUrl = url;
  81. message.mediaObject = webpageObject;
  82. SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
  83. req.bText = NO;
  84. req.message = message;
  85. req.scene = WXSceneSession;
  86. [WXApi sendReq:req completion:nil];
  87. }
  88. /**
  89. 分享给微信朋友圈链接
  90. @param title 标题
  91. @param description 描述
  92. @param image 缩略图
  93. @param url url
  94. */
  95. - (void)share_PYQURLWithTitle:(NSString *)title description:(NSString *)description thumbImage:(UIImage *)image url:(NSString *)url {
  96. /// 大小不能超过64K
  97. UIImage *thumbUrlImage = [UIImage imageWithMaxSide:80.0f sourceImage:image];
  98. WXMediaMessage *message = [WXMediaMessage message];
  99. message.title = title;
  100. message.description = description;
  101. [message setThumbImage:thumbUrlImage];
  102. WXWebpageObject *webpageObject = [WXWebpageObject object];
  103. webpageObject.webpageUrl = url;
  104. message.mediaObject = webpageObject;
  105. SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
  106. req.bText = NO;
  107. req.message = message;
  108. req.scene = WXSceneTimeline;
  109. [WXApi sendReq:req completion:nil];
  110. }
  111. /**
  112. 分享到小程序
  113. @param title 标题
  114. @param description 副标题
  115. @param webpageUrl 兼容低版本的网页链接
  116. @param path 小程序的页面路径
  117. @param hdImage 小程序新版本的预览图二进制数据
  118. */
  119. - (void)share_miniProgramWithTitle:(NSString *)title description:(NSString *)description webpageUrl:(NSString *)webpageUrl path:(NSString *)path hdImage:(UIImage *)hdImage {
  120. // /// 等比例压缩
  121. // CGFloat imagWidth = 200.0f;
  122. // hdImage = [UIImage imageCompressForSize:hdImage targetSize:CGSizeMake(imagWidth, imagWidth/5*4)];
  123. // NSData *imageData = UIImageJPEGRepresentation(hdImage, 1);
  124. NSData *imageData = [self resetSizeOfImageData:hdImage maxSize:128];
  125. NSData *urlimageData = [self resetSizeOfImageData:hdImage maxSize:32];
  126. // if (imageData.length/1024 > 32) {
  127. // /// url分享的图片需要小于32k
  128. // UIImage *thumbUrlImage = [UIImage imageWithMaxSide:50.0f sourceImage:hdImage];
  129. // urlimageData = UIImageJPEGRepresentation(thumbUrlImage, 1);
  130. // }
  131. /// 小程序原始id
  132. NSString *userName = @"gh_7c6684f2120b";
  133. WXMiniProgramObject *object = [WXMiniProgramObject object];
  134. /// 兼容低版本的网页链接 限制长度不超过10KB
  135. object.webpageUrl = webpageUrl;
  136. /// 小程序的userName 小程序原始ID获取方法:登录小程序管理后台-设置-基本设置-帐号信息
  137. object.userName = userName;
  138. /// 小程序的页面路径
  139. object.path = path;
  140. /// 小程序新版本的预览图二进制数据,6.5.9及以上版本微信客户端支持
  141. /// 限制大小不超过128KB,自定义图片建议长宽比是 5:4。
  142. /// 大小不能超过128k
  143. object.hdImageData = imageData;
  144. /// 是否使用带shareTicket的分享
  145. object.withShareTicket = NO;
  146. /// 小程序的类型,默认正式版,1.8.1及以上版本开发者工具包支持分享开发版和体验版小程序
  147. if ([ZYLService currentService] == ZYLServiceEnvironmentRelease) {
  148. object.miniProgramType = WXMiniProgramTypeRelease;
  149. }else {
  150. object.miniProgramType = WXMiniProgramTypePreview;
  151. }
  152. WXMediaMessage *message = [WXMediaMessage message];
  153. message.title = title;
  154. message.description = description;
  155. message.thumbData = urlimageData; //兼容旧版本节点的图片,小于32KB,新版本优先
  156. //使用WXMiniProgramObject的hdImageData属性
  157. message.mediaObject = object;
  158. SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
  159. req.bText = NO;
  160. req.message = message;
  161. req.scene = WXSceneSession; //目前只支持会话
  162. [WXApi sendReq:req completion:nil];
  163. }
  164. /**
  165. 分享文字到新浪微博
  166. @param text 要分享的文字
  167. @return 是否成功
  168. */
  169. - (BOOL)share_sinaTextWithText:(NSString *)text {
  170. WBMessageObject *message = [WBMessageObject message];
  171. message.text = text;
  172. WBProvideMessageForWeiboResponse *response = [WBProvideMessageForWeiboResponse responseWithMessage:message];
  173. return [WeiboSDK sendResponse:response];
  174. }
  175. /**
  176. 分享图片到新浪微博
  177. @param images 要分享的图片数组
  178. @return 是否成功
  179. */
  180. - (BOOL)share_sinaImageWithImages:(NSArray *)images {
  181. WBMessageObject *message = [WBMessageObject message];
  182. WBImageObject *imageObject = [WBImageObject object];
  183. imageObject.isShareToStory = YES;
  184. imageObject.delegate = self;
  185. [imageObject addImages:images];
  186. message.imageObject = imageObject;
  187. WBProvideMessageForWeiboResponse *response = [WBProvideMessageForWeiboResponse responseWithMessage:message];
  188. return [WeiboSDK sendResponse:response];
  189. }
  190. /**
  191. 分享链接到新浪微博
  192. @param url 要分享的链接
  193. @return 是否成功
  194. */
  195. - (BOOL)share_sinaUrlWithUrl:(NSString *)url title:(NSString *)title description:(NSString *)description thumbImage:(UIImage *)image {
  196. WBMessageObject *message = [WBMessageObject message];
  197. WBWebpageObject *webpage = [WBWebpageObject object];
  198. webpage.objectID = @"identifier1";
  199. webpage.title = NSLocalizedString(title, nil);
  200. webpage.description = [NSString stringWithFormat:NSLocalizedString(description, nil), [[NSDate date] timeIntervalSince1970]];
  201. webpage.thumbnailData = UIImagePNGRepresentation(image);
  202. webpage.webpageUrl = url;
  203. message.mediaObject = webpage;
  204. WBProvideMessageForWeiboResponse *response = [WBProvideMessageForWeiboResponse responseWithMessage:message];
  205. return [WeiboSDK sendResponse:response];
  206. }
  207. /**
  208. 分享视频到新浪微博
  209. @param url 要分享的视频链接
  210. @return 是否成功
  211. */
  212. - (BOOL)share_sinaVideoWithVideoUrl:(NSString *)url title:(NSString *)title description:(NSString *)description thumbImage:(UIImage *)image {
  213. WBMessageObject *message = [WBMessageObject message];
  214. WBNewVideoObject *videoObject = [WBNewVideoObject object];
  215. videoObject.isShareToStory = YES;
  216. NSURL *videoUrl = [NSURL URLWithString:url];
  217. videoObject.delegate = self;
  218. [videoObject addVideo:videoUrl];
  219. message.videoObject = videoObject;
  220. WBProvideMessageForWeiboResponse *response = [WBProvideMessageForWeiboResponse responseWithMessage:message];
  221. return [WeiboSDK sendResponse:response];
  222. }
  223. /**
  224. 分享纯文本到QQ
  225. @param text 要分享的text
  226. @param type 1QQ好友 2QQ空间
  227. @return 分享回调状态
  228. */
  229. - (QQApiSendResultCode)share_QQTextWithText:(NSString *)text shareType:(NSInteger)type {
  230. QQApiTextObject *txtObj = [QQApiTextObject objectWithText:text];
  231. SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:txtObj];
  232. if (type == 1) {
  233. //将内容分享到qq
  234. return [QQApiInterface sendReq:req];
  235. }else {
  236. //将内容分享到qzone
  237. return [QQApiInterface SendReqToQZone:req];
  238. }
  239. }
  240. /**
  241. 分享图片到QQ
  242. @param image 要分享的图片
  243. @param title 标题
  244. @param description 副标题
  245. @param type 1QQ好友 2QQ空间
  246. @return 分享回调状态
  247. */
  248. - (QQApiSendResultCode)share_QQImageWithImage:(UIImage *)image title:(NSString *)title description:(NSString *)description shareType:(NSInteger)type {
  249. NSData *imgData = UIImagePNGRepresentation(image);
  250. QQApiImageObject *imgObj = [QQApiImageObject objectWithData:imgData
  251. previewImageData:imgData
  252. title:title
  253. description:description];
  254. SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:imgObj];
  255. if (type == 1) {
  256. //将内容分享到qq
  257. return [QQApiInterface sendReq:req];
  258. }else {
  259. //将内容分享到qzone
  260. return [QQApiInterface SendReqToQZone:req];
  261. }
  262. }
  263. /**
  264. 分享url到QQ
  265. @param url 要分享的url
  266. @param title 标题
  267. @param description 副标题
  268. @param imageUrl 图片url
  269. @param type 1QQ好友 2QQ空间
  270. @return 分享回调状态
  271. */
  272. - (QQApiSendResultCode)share_QQUrlWithUrl:(NSString *)url title:(NSString *)title description:(NSString *)description previewImageURL:(NSString *)imageUrl shareType:(NSInteger)type {
  273. NSArray *arr = [url componentsSeparatedByString:@"&t"];
  274. url = [arr firstObject];
  275. QQApiNewsObject *newsObj = [QQApiNewsObject
  276. objectWithURL:[NSURL URLWithString:url]
  277. title:title
  278. description:description
  279. previewImageURL:[NSURL URLWithString:imageUrl]];
  280. SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
  281. if (type == 1) {
  282. //将内容分享到qq
  283. return [QQApiInterface sendReq:req];
  284. }else {
  285. //将内容分享到qzone
  286. return [QQApiInterface SendReqToQZone:req];
  287. }
  288. }
  289. /**
  290. 分享视频到QQ
  291. @param videoUrl 要分享的视频url
  292. @param title 标题
  293. @param description 副标题
  294. @param image 图片
  295. @param type 1QQ好友 2QQ空间
  296. @return 分享回调状态
  297. */
  298. - (QQApiSendResultCode)share_QQVideoWithVideoUrl:(NSString *)videoUrl title:(NSString *)title description:(NSString *)description previewImage:(UIImage *)image shareType:(NSInteger)type {
  299. NSData* previewData = UIImagePNGRepresentation(image);
  300. QQApiVideoObject *videoObj = [QQApiVideoObject objectWithURL:[NSURL URLWithString:videoUrl ? : @""]
  301. title:title
  302. description:description
  303. previewImageData:previewData];
  304. [videoObj setFlashURL:[NSURL URLWithString:videoUrl]];
  305. SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:videoObj];
  306. if (type == 1) {
  307. //将内容分享到qq
  308. return [QQApiInterface sendReq:req];
  309. }else {
  310. //将内容分享到qzone
  311. return [QQApiInterface SendReqToQZone:req];
  312. }
  313. }
  314. #pragma mark - WBHttpRequestDelegate
  315. - (void)request:(WBHttpRequest *)request didFinishLoadingWithResult:(NSString *)result {
  316. NSLog(@"result:%@", result);
  317. }
  318. - (void)request:(WBHttpRequest *)request didFailWithError:(NSError *)error {
  319. NSLog(@"error:%@", error);
  320. }
  321. #pragma mark - WBMediaTransferProtocol
  322. /**
  323. 数据准备成功回调
  324. */
  325. -(void)wbsdk_TransferDidReceiveObject:(id)object {
  326. NSLog(@"object:%@", object);
  327. }
  328. /**
  329. 数据准备失败回调
  330. */
  331. -(void)wbsdk_TransferDidFailWithErrorCode:(WBSDKMediaTransferErrorCode)errorCode andError:(NSError*)error {
  332. NSLog(@"error:%@", error);
  333. }
  334. #pragma mark - 图片压缩
  335. - (NSData *)resetSizeOfImageData:(UIImage *)sourceImage maxSize:(NSInteger)maxSize {
  336. //先判断当前质量是否满足要求,不满足再进行压缩
  337. __block NSData *finallImageData = UIImageJPEGRepresentation(sourceImage, 1.0);
  338. NSUInteger sizeOrigin = finallImageData.length;
  339. NSUInteger sizeOriginKB = sizeOrigin / 1000;
  340. if (sizeOriginKB <= maxSize) {
  341. return finallImageData;
  342. }
  343. //获取原图片宽高比
  344. CGFloat sourceImageAspectRatio = sourceImage.size.width / sourceImage.size.height;
  345. //先调整分辨率
  346. CGSize defaultSize = CGSizeMake(1024, 1024 / sourceImageAspectRatio);
  347. UIImage * newImage = [self newSizeImage:defaultSize image:sourceImage];
  348. finallImageData = UIImageJPEGRepresentation(newImage, 1.0);
  349. //保存压缩系数
  350. NSMutableArray *compressionQualityArr = [NSMutableArray array];
  351. CGFloat avg = 1.0 / 250;
  352. CGFloat value = avg;
  353. for (int i = 250; i >= 1; i --) {
  354. value = i * avg;
  355. [compressionQualityArr addObject:@(value)];
  356. }
  357. /*
  358. 调整大小
  359. 说明:压缩系数数组compressionQualityArr是从大到小存储。
  360. */
  361. //思路:使用二分法搜索
  362. finallImageData = [self halfFuntion:compressionQualityArr image:newImage sourceData:finallImageData maxSize:maxSize];
  363. //如果还是未能压缩到指定大小,则进行降分辨率
  364. while (finallImageData.length == 0) {
  365. //每次降100分辨率
  366. CGFloat reduceWidth = 100.0;
  367. CGFloat reduceHeight = 100.0 / sourceImageAspectRatio;
  368. if (defaultSize.width - reduceWidth <= 0 || defaultSize.height - reduceHeight <= 0) {
  369. break;
  370. }
  371. defaultSize = CGSizeMake(defaultSize.width - reduceWidth, defaultSize.height - reduceHeight);
  372. UIImage *image = [self newSizeImage:defaultSize
  373. image:[UIImage imageWithData:UIImageJPEGRepresentation(newImage, [[compressionQualityArr lastObject] floatValue])]];
  374. finallImageData = [self halfFuntion:compressionQualityArr image:image sourceData:UIImageJPEGRepresentation(image,1.0) maxSize:maxSize];
  375. }
  376. return finallImageData;
  377. }
  378. #pragma mark 调整图片分辨率/尺寸(等比例缩放)
  379. - (UIImage *)newSizeImage:(CGSize)size image:(UIImage *)sourceImage {
  380. CGSize newSize = CGSizeMake(sourceImage.size.width, sourceImage.size.height);
  381. CGFloat tempHeight = newSize.height / size.height;
  382. CGFloat tempWidth = newSize.width / size.width;
  383. if (tempWidth > 1.0 && tempWidth > tempHeight) {
  384. newSize = CGSizeMake(sourceImage.size.width / tempWidth, sourceImage.size.height / tempWidth);
  385. } else if (tempHeight > 1.0 && tempWidth < tempHeight) {
  386. newSize = CGSizeMake(sourceImage.size.width / tempHeight, sourceImage.size.height / tempHeight);
  387. }
  388. UIGraphicsBeginImageContext(newSize);
  389. [sourceImage drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
  390. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  391. UIGraphicsEndImageContext();
  392. return newImage;
  393. }
  394. #pragma mark 二分法
  395. - (NSData *)halfFuntion:(NSArray *)arr image:(UIImage *)image sourceData:(NSData *)finallImageData maxSize:(NSInteger)maxSize {
  396. NSData *tempData = [NSData data];
  397. NSUInteger start = 0;
  398. NSUInteger end = arr.count - 1;
  399. NSUInteger index = 0;
  400. NSUInteger difference = NSIntegerMax;
  401. while(start <= end) {
  402. index = start + (end - start) / 2;
  403. finallImageData = UIImageJPEGRepresentation(image, [arr[index] floatValue]);
  404. NSUInteger sizeOrigin = finallImageData.length;
  405. NSUInteger sizeOriginKB = sizeOrigin / 1024;
  406. NSLog(@"当前降到的质量:%ld", (unsigned long)sizeOriginKB);
  407. NSLog(@"\nstart:%zd\nend:%zd\nindex:%zd\n压缩系数:%lf", start, end, (unsigned long)index, [arr[index] floatValue]);
  408. if (sizeOriginKB > maxSize) {
  409. start = index + 1;
  410. } else if (sizeOriginKB < maxSize) {
  411. if (maxSize - sizeOriginKB < difference) {
  412. difference = maxSize - sizeOriginKB;
  413. tempData = finallImageData;
  414. }
  415. if (index <= 0) {
  416. break;
  417. }
  418. end = index - 1;
  419. } else {
  420. break;
  421. }
  422. }
  423. return tempData;
  424. }
  425. @end