本节的目标是把长按小视频播放窗口的菜单选项给替换成“Save to Disk”和“Copy URL”,并实现相应动作。有了9.3节的原型作为铺垫,这一节就没什么太多可解释的了,咱们直接动手吧。
新建iOSREWCVideoDownloaders工程的命令如下:
hangcom-mba:Documents sam$ /opt/theos/bin/nic.pl NIC 2.0 - New Instance Creator ------------------------------ [1.] iphone/application [2.] iphone/cydget [3.] iphone/framework [4.] iphone/library [5.] iphone/notification_center_widget [6.] iphone/preference_bundle [7.] iphone/sbsettingstoggle [8.] iphone/tool [9.] iphone/tweak [10.] iphone/xpc_service Choose a Template (required): 9 Project Name (required): iOSREWCVideoDownloader Package Name [com.yourcompany.iosrewcvideodownloader]: com.iosre.iosrewcvideodownloader Author/Maintainer Name [sam]: sam [iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.tencent.xin [iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]: MicroMessenger Instantiating iphone/tweak in iosrewcvideodownloader/... Done.
编辑后的iOSREWCVideoDownloader.h内容如下:
@interface WCContentItem : NSObject @property (retain, nonatomic) NSMutableArray *mediaList; @end @interface WCDataItem : NSObject @property (retain, nonatomic) WCContentItem *contentObj; @end @interface WCUrl : NSObject @property (retain, nonatomic) NSString *url; @end @interface WCMediaItem : NSObject @property (retain, nonatomic) WCUrl *dataUrl; - (id)pathForSightData; @end @interface WCContentItemViewTemplateNewSight : UIView - (WCMediaItem *)iOSREMediaItemFromSight; - (void)iOSREOnSaveToDisk; - (void)iOSREOnCopyURL; @end @interface MMServiceCenter : NSObject + (id)defaultCenter; - (id)getService:(Class)arg1; @end @interface WCFacade : NSObject - (WCDataItem *)getTimelineDataItemOfIndex:(int)arg1; @end @interface WCTimeLineViewController : NSObject - (int)calcDataItemIndex:(int)arg1; @end @interface MMTableViewCell : UITableViewCell @end @interface MMTableView : UITableView @end
这个头文件的所有内容均摘自类对应的头文件,构造它的目的仅仅是通过编译,避免出现任何报错信息和警告。
编辑后的Tweak.xm内容如下:
#import "iOSREWCVideoDownloader.h" static MMTableViewCell *iOSRECell; static MMTableView *iOSREView; static WCTimeLineViewController *iOSREController; %hook WCContentItemViewTemplateNewSight %new - (WCMediaItem *)iOSREMediaItemFromSight { id responder = self; while (![responder isKindOfClass:NSClassFromString(@"WCTimeLineViewController")]) { if ([responder isKindOfClass:NSClassFromString(@"MMTableViewCell")]) iOSRECell = responder; else if ([responder isKindOfClass:NSClassFromString(@"MMTableView")]) iOSREView = responder; responder = [responder nextResponder]; } iOSREController = responder; if (!iOSRECell || !iOSREView || !iOSREController) { NSLog(@"iOSRE: Failed to get video object."); return nil; } NSIndexPath *indexPath = [iOSREView indexPathForCell:iOSRECell]; int itemIndex = [iOSREController calcDataItemIndex:[indexPath section]]; WCFacade *facade = [(MMServiceCenter *)[%c(MMServiceCenter) defaultCenter] getService:[%c(WCFacade) class]]; WCDataItem *dataItem = [facade getTimelineDataItemOfIndex:itemIndex]; WCContentItem *contentItem = dataItem.contentObj; WCMediaItem *mediaItem = [contentItem.mediaList count] != 0 ? (contentItem.mediaList)[0] : nil; return mediaItem; } %new - (void)iOSREOnSaveToDisk { NSString *localPath = [[self iOSREMediaItemFromSight] pathForSightData]; UISaveVideoAtPathToSavedPhotosAlbum(localPath, nil, nil, nil); } %new - (void)iOSREOnCopyURL { UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; pasteboard.string = [self iOSREMediaItemFromSight].dataUrl.url; } static int iOSRECounter; - (void)onLongTouch { iOSRECounter++; if (iOSRECounter % 2 == 0) return; [self becomeFirstResponder]; UIMenuItem *saveToDiskMenuItem = [[UIMenuItem alloc] initWithTitle:@"Save to Disk" action:@selector(iOSREOnSaveToDisk)]; UIMenuItem *copyURLMenuItem = [[UIMenuItem alloc] initWithTitle:@"Copy URL" action:@selector(iOSREOnCopyURL)]; UIMenuController *menuController = [UIMenuController sharedMenuController]; [menuController setMenuItems:@[saveToDiskMenuItem, copyURLMenuItem]]; [menuController setTargetRect:CGRectZero inView:self]; [menuController setMenuVisible:YES animated:YES]; [saveToDiskMenuItem release]; [copyURLMenuItem release]; } %end
编辑后的Makefile内容如下:
THEOS_DEVICE_IP = iOSIP TARGET = iphone:latest:8.0 ARCHS = armv7 arm64 include theos/makefiles/common.mk TWEAK_NAME = iOSREWCVideoDownloader iOSREWCVideoDownloader_FILES = Tweak.xm iOSREWCVideoDownloader_FRAMEWORKS = UIKit include $(THEOS_MAKE_PATH)/tweak.mk after-install:: install.exec "killall -9 MicroMessenger"
编辑后的control内容如下:
Package: com.iosre.iosrewcvideodownloader Name: iOSREWCVideoDownloader Depends: mobilesubstrate, firmware (>= 8.0) Version: 1.0 Architecture: iphoneos-arm Description: Play with Sight! Maintainer: sam Author: sam Section: Tweaks Homepage: http://bbs.iosre.com
将写好的tweak编译打包安装到iOS后,打开微信,长按小视频播放窗口,就会弹出自定义菜单,如图9-29所示。
图9-29 自定义菜单
点击“Save to Disk”,这个小视频会被保存到相册中,如图9-30所示。
点击“Copy URL”,然后到OPlayer Lite(或任意支持在线视频播放的App)中打开这个网址,如图9-31所示。
图9-30 把小视频保存到相册
图9-31 在OPlayer Lite中播放在线mp4
所有功能均可正常工作,本章任务达成!