├── ScreenRecoderForGame ├── Pods │ ├── Headers │ │ ├── Private │ │ │ └── JSPatch │ │ │ │ └── JPEngine.h │ │ └── Public │ │ │ └── JSPatch │ │ │ └── JPEngine.h │ ├── Target Support Files │ │ ├── JSPatch │ │ │ ├── JSPatch-prefix.pch │ │ │ ├── JSPatch-dummy.m │ │ │ └── JSPatch.xcconfig │ │ └── Pods-ScreenRecoderForGame │ │ │ ├── Pods-ScreenRecoderForGame-dummy.m │ │ │ ├── Pods-ScreenRecoderForGame.debug.xcconfig │ │ │ ├── Pods-ScreenRecoderForGame.release.xcconfig │ │ │ ├── Pods-ScreenRecoderForGame-acknowledgements.markdown │ │ │ ├── Pods-ScreenRecoderForGame-acknowledgements.plist │ │ │ ├── Pods-ScreenRecoderForGame-frameworks.sh │ │ │ └── Pods-ScreenRecoderForGame-resources.sh │ ├── Manifest.lock │ ├── JSPatch │ │ ├── LICENSE │ │ ├── JSPatch │ │ │ ├── JPEngine.h │ │ │ ├── JSPatch.js │ │ │ └── JPEngine.m │ │ └── README-CN.md │ └── Pods.xcodeproj │ │ └── project.pbxproj ├── ScreenRecoderForGame │ ├── 0.png │ ├── 1.gif │ ├── a.mp3 │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── AppDelegate.m │ └── ViewController.m ├── Podfile.lock ├── ScreenRecoderForGame.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj ├── ScreenRecoderForGame.xcworkspace │ └── contents.xcworkspacedata ├── Podfile ├── ScreenRecoderForGameTests │ ├── Info.plist │ └── ScreenRecoderForGameTests.m ├── ScreenRecoderForGameUITests │ ├── Info.plist │ └── ScreenRecoderForGameUITests.m ├── GameScreenRecoder.h └── GameScreenRecoder.m ├── README.md ├── LICENSE └── .gitignore /ScreenRecoderForGame/Pods/Headers/Private/JSPatch/JPEngine.h: -------------------------------------------------------------------------------- 1 | ../../../JSPatch/JSPatch/JPEngine.h -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Headers/Public/JSPatch/JPEngine.h: -------------------------------------------------------------------------------- 1 | ../../../JSPatch/JSPatch/JPEngine.h -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ScreenRecord 2 | iOS 9.0 新增的接口,屏幕录制,声音录制,可以选择是否启用麦克风录入外围环境声音。 3 | 4 | 已经封装好为一个类,直接在项目中拖入就可以使用。 5 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/JSPatch/JSPatch-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topws/ScreenRecord/HEAD/ScreenRecoderForGame/ScreenRecoderForGame/0.png -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topws/ScreenRecord/HEAD/ScreenRecoderForGame/ScreenRecoderForGame/1.gif -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/a.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topws/ScreenRecord/HEAD/ScreenRecoderForGame/ScreenRecoderForGame/a.mp3 -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/JSPatch/JSPatch-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_JSPatch : NSObject 3 | @end 4 | @implementation PodsDummy_JSPatch 5 | @end 6 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ScreenRecoderForGame : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ScreenRecoderForGame 5 | @end 6 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - JSPatch (1.0): 3 | - JSPatch/Core (= 1.0) 4 | - JSPatch/Core (1.0) 5 | 6 | DEPENDENCIES: 7 | - JSPatch (~> 1.0) 8 | 9 | SPEC CHECKSUMS: 10 | JSPatch: c689ea4dde17441f2f4a95d40dfedb8900c20099 11 | 12 | COCOAPODS: 0.39.0 13 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - JSPatch (1.0): 3 | - JSPatch/Core (= 1.0) 4 | - JSPatch/Core (1.0) 5 | 6 | DEPENDENCIES: 7 | - JSPatch (~> 1.0) 8 | 9 | SPEC CHECKSUMS: 10 | JSPatch: c689ea4dde17441f2f4a95d40dfedb8900c20099 11 | 12 | COCOAPODS: 0.39.0 13 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ScreenRecoderForGame 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/JSPatch/JSPatch.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/JSPatch" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/JSPatch" 3 | OTHER_LDFLAGS = -framework "Foundation" -weak_framework "JavaScriptCore" 4 | PODS_ROOT = ${SRCROOT} 5 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /ScreenRecoderForGame/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '8.0' 3 | # Uncomment this line if you're using Swift 4 | # use_frameworks! 5 | 6 | target 'ScreenRecoderForGame' do 7 | pod 'JSPatch', '~> 1.0' 8 | end 9 | 10 | target 'ScreenRecoderForGameTests' do 11 | 12 | end 13 | 14 | target 'ScreenRecoderForGameUITests' do 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ScreenRecoderForGame 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ScreenRecoderForGame 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/JSPatch" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/JSPatch" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"JSPatch" -framework "Foundation" -weak_framework "JavaScriptCore" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/JSPatch" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/JSPatch" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"JSPatch" -framework "Foundation" -weak_framework "JavaScriptCore" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGameTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGameUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/GameScreenRecoder.h: -------------------------------------------------------------------------------- 1 | // 2 | // GameScreenRecoder.h 3 | // ScreenRecoderForGame 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @protocol GameScreenRecoderDelegate 12 | 13 | @required 14 | //预览准备的视频 15 | -(void)showSuccessViewController; 16 | //点击取消或者村村后要移除这个页面 17 | - (void)previewControllerDidFinish:(RPPreviewViewController *)previewController; 18 | //根据需要进行用户提示 19 | - (void)previewController:(RPPreviewViewController *)previewController didFinishWithActivityTypes:(NSSet *)activityTypes; 20 | 21 | @optional 22 | //正在录屏 23 | -(void)loading; 24 | //结束录屏 25 | -(void)loadEnd; 26 | @end 27 | 28 | @interface GameScreenRecoder : NSObject 29 | 30 | @property(nonatomic,weak)id delegate; 31 | +(instancetype)INSTANCE; 32 | 33 | //开始录屏是否需要启用麦克风 34 | +(BOOL)startRecord:(BOOL)isNeedMicroPhone; 35 | +(void)stopRecord; 36 | @end 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 topws 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGameTests/ScreenRecoderForGameTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ScreenRecoderForGameTests.m 3 | // ScreenRecoderForGameTests 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ScreenRecoderForGameTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ScreenRecoderForGameTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/JSPatch/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 bang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## JSPatch 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 bang 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | Generated by CocoaPods - http://cocoapods.org 30 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGameUITests/ScreenRecoderForGameUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ScreenRecoderForGameUITests.m 3 | // ScreenRecoderForGameUITests 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ScreenRecoderForGameUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ScreenRecoderForGameUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationLandscapeLeft 36 | UIInterfaceOrientationLandscapeRight 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationPortraitUpsideDown 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ScreenRecoderForGame 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 bang 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | 40 | Title 41 | JSPatch 42 | Type 43 | PSGroupSpecifier 44 | 45 | 46 | FooterText 47 | Generated by CocoaPods - http://cocoapods.org 48 | Title 49 | 50 | Type 51 | PSGroupSpecifier 52 | 53 | 54 | StringsTable 55 | Acknowledgements 56 | Title 57 | Acknowledgements 58 | 59 | 60 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/JSPatch/JSPatch/JPEngine.h: -------------------------------------------------------------------------------- 1 | // 2 | // JPEngine.h 3 | // JSPatch 4 | // 5 | // Created by bang on 15/4/30. 6 | // Copyright (c) 2015 bang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface JPEngine : NSObject 14 | 15 | /*! 16 | @method 17 | @discussion start the JSPatch engine, execute only once. 18 | */ 19 | + (void)startEngine; 20 | 21 | /*! 22 | @method 23 | @description Evaluate Javascript code from a file Path. Call it after +startEngine. 24 | @param filePath: The filePath of the Javascript code. 25 | @result The last value generated by the script. 26 | */ 27 | + (JSValue *)evaluateScriptWithPath:(NSString *)filePath; 28 | 29 | /*! 30 | @method 31 | @description Evaluate a string of JavaScript code. Call it after +startEngine. 32 | The method will generate a default resouceURL named "main.js" to the Safari debugger. 33 | @param script: A string containing the JavaScript code to evaluate. 34 | @result The last value generated by the script. 35 | */ 36 | + (JSValue *)evaluateScript:(NSString *)script; 37 | 38 | /*! 39 | @method 40 | @description Return the JSPatch JavaScript execution environment. 41 | */ 42 | + (JSContext *)context; 43 | 44 | 45 | 46 | /*! 47 | @method 48 | @description Add JPExtension. 49 | @param extensions: An array containing class name string. 50 | */ 51 | + (void)addExtensions:(NSArray *)extensions; 52 | 53 | /*! 54 | @method 55 | @description add new struct type supporting to JS 56 | @param defineDict: the definition of struct, for Example: 57 | @{ 58 | @"name": @"CGAffineTransform", //struct name 59 | @"types": @"ffffff", //struct types 60 | @"keys": @[@"a", @"b", @"c", @"d", @"tx", @"ty"] //struct keys in JS 61 | } 62 | */ 63 | + (void)defineStruct:(NSDictionary *)defineDict; 64 | 65 | @end 66 | 67 | 68 | 69 | @interface JPExtension : NSObject 70 | + (void)main:(JSContext *)context; 71 | 72 | + (void *)formatPointerJSToOC:(JSValue *)val; 73 | + (id)formatRetainedCFTypeOCToJS:(CFTypeRef)CF_CONSUMED type; 74 | + (id)formatPointerOCToJS:(void *)pointer; 75 | + (id)formatJSToOC:(JSValue *)val; 76 | + (id)formatOCToJS:(id)obj; 77 | 78 | + (int)sizeOfStructTypes:(NSString *)structTypes; 79 | + (void)getStructDataWidthDict:(void *)structData dict:(NSDictionary *)dict structDefine:(NSDictionary *)structDefine; 80 | + (NSDictionary *)getDictOfStruct:(void *)structData structDefine:(NSDictionary *)structDefine; 81 | 82 | /*! 83 | @method 84 | @description Return the registered struct definition in JSPatch, 85 | the key of dictionary is the struct name. 86 | */ 87 | + (NSMutableDictionary *)registeredStruct; 88 | 89 | + (NSDictionary *)overideMethods; 90 | @end 91 | 92 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ScreenRecoderForGame 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | #import 12 | #import "GameScreenRecoder.h" 13 | 14 | @interface ViewController () 15 | @property (weak, nonatomic) IBOutlet UIImageView *backImageView; 16 | @property (weak, nonatomic) IBOutlet UILabel *timeLabel; 17 | @property (strong,nonatomic)AVAudioPlayer * player; 18 | @property (nonatomic,strong)NSTimer * timer; 19 | @property (weak, nonatomic) IBOutlet UILabel *flagLabel; 20 | @end 21 | 22 | @implementation ViewController 23 | -(NSTimer *)timer{ 24 | if (_timer == nil) { 25 | _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeBegin) userInfo:nil repeats:YES]; 26 | } 27 | return _timer; 28 | } 29 | -(void)timeBegin{ 30 | _timeLabel.text = [NSString stringWithFormat:@"%ld",[_timeLabel.text integerValue]+1]; 31 | } 32 | - (void)viewDidLoad { 33 | [super viewDidLoad]; 34 | UIImage * image1 = [UIImage imageNamed:@"0.png"]; 35 | UIImage * image2 = [UIImage imageNamed:@"1.gif"]; 36 | self.backImageView.animationImages = @[image1,image2]; 37 | self.backImageView.animationDuration = 3.0; 38 | self.backImageView.animationRepeatCount = 0; 39 | [self.backImageView startAnimating]; 40 | [self createMusic]; 41 | [self.timer fire]; 42 | [GameScreenRecoder INSTANCE].delegate = self; 43 | self.flagLabel.text = @"状态"; 44 | 45 | } 46 | 47 | - (void)didReceiveMemoryWarning { 48 | [super didReceiveMemoryWarning]; 49 | // Dispose of any resources that can be recreated. 50 | } 51 | - (void)dealloc{ 52 | [self.timer invalidate]; 53 | self.timer = nil; 54 | } 55 | - (IBAction)startRecord:(id)sender { 56 | //同时开启音乐 57 | [_player play]; 58 | if ([GameScreenRecoder startRecord:YES]) { 59 | [self.timer fire]; 60 | NSLog(@"开始录制"); 61 | } 62 | } 63 | - (IBAction)endRecord:(id)sender { 64 | [_player stop]; 65 | [GameScreenRecoder stopRecord]; 66 | self.flagLabel.text = @"录制结束"; 67 | [self.timer invalidate]; 68 | self.timer = nil; 69 | NSLog(@"结束"); 70 | } 71 | #pragma mark -Delegate 72 | -(void)loading{ 73 | self.flagLabel.text = @"准备中"; 74 | } 75 | -(void)loadEnd{ 76 | self.flagLabel.text = @"正在录制"; 77 | } 78 | -(void)showSuccessViewController{ 79 | 80 | } 81 | - (void)previewControllerDidFinish:(RPPreviewViewController *)previewController{ 82 | NSLog(@"%s",__FUNCTION__); 83 | NSLog(@"%@",previewController); 84 | [previewController dismissViewControllerAnimated:YES completion:^{ 85 | 86 | }]; 87 | 88 | } 89 | - (void)previewController:(RPPreviewViewController *)previewController didFinishWithActivityTypes:(NSSet *)activityTypes{ 90 | NSLog(@"展示视图的内容%@",activityTypes); 91 | if ([activityTypes containsObject:@"com.apple.UIKit.activity.SaveToCameraRoll"]) { 92 | NSLog(@"已保存到用户相册,如果有需要可以提示用户,弹出一个对话框"); 93 | } 94 | //"com.apple.UIKit.activity.CopyToPasteboard"拷贝了该文件 95 | 96 | } 97 | #pragma mark -音乐播放 98 | -(void)createMusic{ 99 | NSURL * url = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@"a" ofType:@"mp3"]]; 100 | AVAudioPlayer * player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil]; 101 | player.volume = 1.0; 102 | self.player = player; 103 | [player prepareToPlay]; 104 | 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/GameScreenRecoder.m: -------------------------------------------------------------------------------- 1 | // 2 | // GameScreenRecoder.m 3 | // ScreenRecoderForGame 4 | // 5 | // Created by qianwei on 16/4/21. 6 | // Copyright © 2016年 qianwei. All rights reserved. 7 | // 8 | 9 | #import "GameScreenRecoder.h" 10 | 11 | 12 | #if TARGET_IPHONE_SIMULATOR 13 | #define SIMULATOR 1 14 | #elif TARGET_OS_IPHONE 15 | #define SIMULATOR 0 16 | #endif 17 | 18 | @interface GameScreenRecoder() 19 | //@property (nonatomic,strong) 20 | @property (assign,nonatomic)BOOL isRecord; 21 | //加载中的提示,可以自行替换 22 | @property(nonatomic,strong)UIActivityIndicatorView * indicator; 23 | @end 24 | 25 | @implementation GameScreenRecoder 26 | +(instancetype)INSTANCE{ 27 | static id instance; 28 | static dispatch_once_t onceToken; 29 | dispatch_once(&onceToken, ^{ 30 | instance = [[self alloc]init]; 31 | }); 32 | return instance; 33 | } 34 | +(BOOL)startRecord:(BOOL)isNeedMicroPhone{ 35 | return [[self INSTANCE]start:isNeedMicroPhone]; 36 | } 37 | +(void)stopRecord{ 38 | [[self INSTANCE]stop]; 39 | } 40 | -(instancetype)init{ 41 | if (self = [super init]) { 42 | _isRecord = NO; 43 | [RPScreenRecorder sharedRecorder].delegate = self; 44 | } 45 | return self; 46 | } 47 | -(UIActivityIndicatorView *)indicator{ 48 | if (_indicator == nil) { 49 | _indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 50 | UIView * view = [UIApplication sharedApplication].keyWindow.rootViewController.view; 51 | _indicator.bounds = CGRectMake(0, 0, 50, 50); 52 | _indicator.center = view.center; 53 | [view addSubview:_indicator]; 54 | } 55 | return _indicator; 56 | } 57 | //开始录制 58 | -(BOOL)start:(BOOL)isNeedMicroPhone{ 59 | if (![self isSystemVersionOk]) { 60 | return NO; 61 | } 62 | //不支持模拟器 63 | if (SIMULATOR) { 64 | [self showSimulatorWarning]; 65 | return NO; 66 | } 67 | if (![RPScreenRecorder sharedRecorder].isAvailable) { 68 | NSLog(@"不支持ReplayKit录制"); 69 | return NO; 70 | } 71 | //系统自带的接口,判断是否在录制,比我的好用多了 72 | NSLog(@"%d",[[RPScreenRecorder sharedRecorder]isRecording]); 73 | if ([[RPScreenRecorder sharedRecorder]isRecording]) { 74 | return NO; 75 | } 76 | 77 | 78 | if ([self isRecord]) { 79 | return NO; 80 | } 81 | self.isRecord = YES; 82 | //开始录制(参数是是否启用麦克风)(回调是 录制是否准备完毕 83 | [[self indicator]startAnimating]; 84 | if ([[self delegate] respondsToSelector:@selector(loading)]) { 85 | [[self delegate]loading]; 86 | } 87 | [[RPScreenRecorder sharedRecorder]startRecordingWithMicrophoneEnabled:isNeedMicroPhone handler:^(NSError * _Nullable error) { 88 | if (error) { 89 | NSLog(@"录制失败 %@",error); 90 | self.isRecord = NO; 91 | 92 | }else{ 93 | //加载完毕 94 | if ([[self delegate] respondsToSelector:@selector(loadEnd)]) { 95 | [[self delegate]loadEnd]; 96 | } 97 | } 98 | [[self indicator]stopAnimating]; 99 | }]; 100 | return YES; 101 | } 102 | //结束录制 103 | -(void)stop{ 104 | NSLog(@"结束录制"); 105 | self.isRecord = NO; 106 | 107 | //应该修改提示文字 108 | 109 | [[RPScreenRecorder sharedRecorder]stopRecordingWithHandler:^(RPPreviewViewController * _Nullable previewViewController, NSError * _Nullable error) { 110 | if (!error) { 111 | //让代理控制器来展示 112 | if ([self.delegate respondsToSelector:@selector(showSuccessViewController)]) 113 | { 114 | if ([self.delegate isKindOfClass:[UIViewController class]]) 115 | { 116 | UIViewController * vc = (UIViewController *)self.delegate; 117 | previewViewController.previewControllerDelegate = vc; 118 | NSLog(@"%@",[NSThread currentThread]); 119 | //回到主线程展示页面 120 | [vc presentViewController:previewViewController animated:YES completion:^{ 121 | 122 | }]; 123 | 124 | 125 | } 126 | } 127 | } 128 | }]; 129 | } 130 | #pragma mark RPScreenRecordDelegate 131 | - (void)screenRecorder:(RPScreenRecorder *)screenRecorder didStopRecordingWithError:(NSError *)error previewViewController:(nullable RPPreviewViewController *)previewViewController 132 | { 133 | NSLog(@"%s error = %@",__FUNCTION__,error); 134 | } 135 | 136 | - (void)screenRecorderDidChangeAvailability:(RPScreenRecorder *)screenRecorder 137 | { 138 | //如果变成了无法录屏,应该发送通知去停止录屏 139 | NSLog(@"屏幕录制的能力改变了 %d %d",screenRecorder.isRecording,screenRecorder.isAvailable); 140 | } 141 | 142 | 143 | -(void)showSimulatorWarning{ 144 | NSLog(@"不支持模拟器"); 145 | } 146 | //判断对应系统版本是否支持ReplayKit 147 | - (BOOL)isSystemVersionOk { 148 | if ([[UIDevice currentDevice].systemVersion floatValue] < 9.0) { 149 | return NO; 150 | } else { 151 | return YES; 152 | } 153 | } 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY="$(cd "${1%/*}" && pwd)" 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 22 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 23 | ;; 24 | *.xib) 25 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 26 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | if [[ "$CONFIGURATION" == "Debug" ]]; then 61 | install_resource "JSPatch/JSPatch/JSPatch.js" 62 | fi 63 | if [[ "$CONFIGURATION" == "Release" ]]; then 64 | install_resource "JSPatch/JSPatch/JSPatch.js" 65 | fi 66 | 67 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 68 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 69 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 70 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 71 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 72 | fi 73 | rm -f "$RESOURCES_TO_COPY" 74 | 75 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 76 | then 77 | case "${TARGETED_DEVICE_FAMILY}" in 78 | 1,2) 79 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 80 | ;; 81 | 1) 82 | TARGET_DEVICE_ARGS="--target-device iphone" 83 | ;; 84 | 2) 85 | TARGET_DEVICE_ARGS="--target-device ipad" 86 | ;; 87 | *) 88 | TARGET_DEVICE_ARGS="--target-device mac" 89 | ;; 90 | esac 91 | 92 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 93 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 94 | while read line; do 95 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 96 | XCASSET_FILES+=("$line") 97 | fi 98 | done <<<"$OTHER_XCASSETS" 99 | 100 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 101 | fi 102 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/JSPatch/README-CN.md: -------------------------------------------------------------------------------- 1 | # JSPatch 2 | 3 | JSPatch 可以让你用 JavaScript 书写原生 iOS APP。只需在项目引入极小的引擎,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,获得脚本语言的优势:为项目动态添加模块,或替换项目原生代码动态修复 bug。 4 | 5 | 项目仍在开发中,欢迎一起完善这个项目。 6 | 7 | **注意**:完善的文档请移步 [Wiki](https://github.com/bang590/JSPatch/wiki/)。 8 | 9 | ## 示例 10 | 11 | ```objc 12 | @implementation AppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | [JPEngine startEngine]; 17 | NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"]; 18 | NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil]; 19 | [JPEngine evaluateScript:script]; 20 | 21 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 22 | [self.window addSubview:[self genView]]; 23 | [self.window makeKeyAndVisible]; 24 | 25 | return YES; 26 | } 27 | 28 | - (UIView *)genView 29 | { 30 | return [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)]; 31 | } 32 | 33 | @end 34 | ``` 35 | 36 | ```js 37 | // demo.js 38 | require('UIView, UIColor, UILabel') 39 | defineClass('AppDelegate', { 40 | // replace the -genView method 41 | genView: function() { 42 | var view = self.ORIGgenView(); 43 | view.setBackgroundColor(UIColor.greenColor()) 44 | var label = UILabel.alloc().initWithFrame(view.frame()); 45 | label.setText("JSPatch"); 46 | label.setTextAlignment(1); 47 | view.addSubview(label); 48 | return view; 49 | } 50 | }); 51 | ``` 52 | 53 | 可以使用 [JSPatch Convertor](https://github.com/bang590/JSPatchConvertor) 自动把 Objective-C 代码转为 JavaScript 代码。 54 | 55 | ## 安装 56 | 57 | 拷贝 `JSPatch/` 目录下的三个文件 `JSEngine.m` / `JSEngine.h` / `JSPatch.js` 到项目里即可。 58 | 59 | ## 使用 60 | 61 | ### Objective-C: 62 | 1. `#import "JPEngine.h"` 63 | 2. 调用`[JPEngine startEngine]` 64 | 3. 通过`[JPEngine evaluateScript:@""]`接口执行 JavaScript。 65 | 66 | ```objc 67 | [JPEngine startEngine]; 68 | 69 | // 直接执行js 70 | [JPEngine evaluateScript:@"\ 71 | var alertView = require('UIAlertView').alloc().init();\ 72 | alertView.setTitle('Alert');\ 73 | alertView.setMessage('AlertView from js'); \ 74 | alertView.addButtonWithTitle('OK');\ 75 | alertView.show(); \ 76 | "]; 77 | 78 | // 从网络拉回js脚本执行 79 | [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://cnbang.net/test.js"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 80 | NSString *script = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 81 | [JPEngine evaluateScript:script]; 82 | }]; 83 | 84 | // 执行本地js文件 85 | NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"js"]; 86 | NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil]; 87 | [JPEngine evaluateScript:script]; 88 | ``` 89 | 90 | ### JavaScript: 91 | 92 | #### 基础使用方式 93 | 94 | ```js 95 | // 调用require引入要使用的OC类 96 | require('UIView, UIColor, UISlider, NSIndexPath') 97 | 98 | // 调用类方法 99 | var redColor = UIColor.redColor(); 100 | 101 | // 调用实例方法 102 | var view = UIView.alloc().init(); 103 | view.setNeedsLayout(); 104 | 105 | // set proerty 106 | view.setBackgroundColor(redColor); 107 | 108 | // get property 109 | var bgColor = view.backgroundColor(); 110 | 111 | // 多参数方法名用'_'隔开: 112 | // OC:NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1]; 113 | var indexPath = NSIndexPath.indexPathForRow_inSection(0, 1); 114 | 115 | // 方法名包含下划线'_',js用双下划线表示 116 | // OC: [JPObject _privateMethod]; 117 | JPObject.__privateMethod() 118 | 119 | // 如果要把 `NSArray` / `NSString` / `NSDictionary` 转为对应的 JS 类型,使用 `.toJS()` 接口. 120 | var arr = require('NSMutableArray').alloc().init() 121 | arr.addObject("JS") 122 | jsArr = arr.toJS() 123 | console.log(jsArr.push("Patch").join('')) //output: JSPatch 124 | 125 | // 在JS用字典的方式表示 CGRect / CGSize / CGPoint / NSRange 126 | var view = UIView.alloc().initWithFrame({x:20, y:20, width:100, height:100}); 127 | var x = view.bounds().x; 128 | 129 | // block 从 JavaScript 传入 Objective-C 时,需要写上每个参数的类型。 130 | // OC Method: + (void)request:(void(^)(NSString *content, BOOL success))callback 131 | require('JPObject').request(block("NSString *, BOOL", function(ctn, succ) { 132 | if (succ) log(ctn) 133 | })); 134 | 135 | // GCD 136 | dispatch_after(function(1.0, function(){ 137 | // do something 138 | })) 139 | dispatch_async_main(function(){ 140 | // do something 141 | }) 142 | ``` 143 | 144 | 详细文档请参考wiki页面:[Base Usage](https://github.com/bang590/JSPatch/wiki/Base-usage) 145 | 146 | 147 | #### 定义类/替换方法 148 | 149 | 用 `defineClass()` 定义 Objective-C 的类,对类和实例方法进行动态替换。 150 | 151 | ```objc 152 | // OC 153 | @implementation JPTableViewController 154 | ... 155 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 156 | { 157 | NSString *content = self.dataSource[[indexPath row]]; //may cause out of bound 158 | JPViewController *ctrl = [[JPViewController alloc] initWithContent:content]; 159 | [self.navigationController pushViewController:ctrl]; 160 | } 161 | - (NSArray *)dataSource 162 | { 163 | return @[@"JSPatch", @"is"]; 164 | } 165 | - (void)customMethod 166 | { 167 | NSLog(@"callCustom method") 168 | } 169 | @end 170 | ``` 171 | 172 | ```objc 173 | // JS 174 | defineClass("JPTableViewController", { 175 | // instance method definitions 176 | tableView_didSelectRowAtIndexPath: function(tableView, indexPath) { 177 | var row = indexPath.row() 178 | if (self.dataSource().count() > row) { //fix the out of bound bug here 179 | var content = self.dataSource().objectAtIndex(row); 180 | var ctrl = JPViewController.alloc().initWithContent(content); 181 | self.navigationController().pushViewController(ctrl); 182 | } 183 | }, 184 | 185 | dataSource: function() { 186 | // get the original method by adding prefix 'ORIG' 187 | var data = self.ORIGdataSource().toJS(); 188 | return data.push('Good!'); 189 | } 190 | }, {}) 191 | ``` 192 | 193 | 详细文档请参考wiki页面:[Usage of defineClass](https://github.com/bang590/JSPatch/wiki/Usage-of-defineClass) 194 | 195 | 196 | #### 扩展 197 | 198 | 一些自定义的struct类型、C函数调用以及其他功能可以通过扩展实现,调用 `+addExtensions:` 可以加载扩展接口: 199 | 200 | ```objc 201 | @implementation AppDelegate 202 | 203 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 204 | { 205 | [JPEngine startEngine]; 206 | 207 | //添加扩展 208 | [JPEngine addExtensions:@[@"JPInclude", @"JPCGTransform"]]; 209 | 210 | NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"]; 211 | NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil]; 212 | [JPEngine evaluateScript:script]; 213 | } 214 | ``` 215 | 216 | ```js 217 | include('test.js') //`include()`方法在扩展 JPInclude.m 里提供 218 | var view = require('UIView').alloc().init() 219 | 220 | //struct CGAffineTransform 类型在 JPCGTransform.m 里提供支持 221 | view.setTransform({a:1, b:0, c:0, d:1, tx:0, ty:100}) 222 | ``` 223 | 224 | 扩展可以在JS动态加载,更推荐这种加载方式,在需要用到时才加载: 225 | 226 | ```js 227 | require('JPEngine').addExtensions(['JPInclude', 'JPCGTransform']) 228 | 229 | // `include()` and `CGAffineTransform` is avaliable now. 230 | ``` 231 | 232 | 可以通过新增扩展为自己项目里的 struct 类型以及C函数添加支持,详情请见wiki页面:[Adding new extensions](https://github.com/bang590/JSPatch/wiki/Adding-new-extensions) 233 | 234 | 235 | ## 运行环境 236 | - iOS 7+ 237 | - JavaScriptCore.framework 238 | - 支持 armv7/armv7s/arm64 239 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 37 | 51 | 62 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/JSPatch/JSPatch/JSPatch.js: -------------------------------------------------------------------------------- 1 | var global = this 2 | 3 | ;(function() { 4 | 5 | var _ocCls = {}; 6 | var _jsCls = {}; 7 | 8 | var _formatOCToJS = function(obj) { 9 | if (obj === undefined || obj === null) return false 10 | if (typeof obj == "object") { 11 | if (obj.__obj) return obj 12 | if (obj.__isNil) return false 13 | } 14 | if (obj instanceof Array) { 15 | var ret = [] 16 | obj.forEach(function(o) { 17 | ret.push(_formatOCToJS(o)) 18 | }) 19 | return ret 20 | } 21 | if (obj instanceof Function) { 22 | return function() { 23 | var args = Array.prototype.slice.call(arguments) 24 | var formatedArgs = _OC_formatJSToOC(args) 25 | for (var i = 0; i < args.length; i++) { 26 | if (args[i] === null || args[i] === undefined || args[i] === false) { 27 | formatedArgs.splice(i, 1, undefined) 28 | } else if (args[i] == nsnull) { 29 | formatedArgs.splice(i, 1, null) 30 | } 31 | } 32 | return _OC_formatOCToJS(obj.apply(obj, formatedArgs)) 33 | } 34 | } 35 | if (obj instanceof Object) { 36 | var ret = {} 37 | for (var key in obj) { 38 | ret[key] = _formatOCToJS(obj[key]) 39 | } 40 | return ret 41 | } 42 | return obj 43 | } 44 | 45 | var _methodFunc = function(instance, clsName, methodName, args, isSuper, isPerformSelector) { 46 | var selectorName = methodName 47 | if (!isPerformSelector) { 48 | methodName = methodName.replace(/__/g, "-") 49 | selectorName = methodName.replace(/_/g, ":").replace(/-/g, "_") 50 | var marchArr = selectorName.match(/:/g) 51 | var numOfArgs = marchArr ? marchArr.length : 0 52 | if (args.length > numOfArgs) { 53 | selectorName += ":" 54 | } 55 | } 56 | var ret = instance ? _OC_callI(instance, selectorName, args, isSuper): 57 | _OC_callC(clsName, selectorName, args) 58 | return _formatOCToJS(ret) 59 | } 60 | 61 | var _customMethods = { 62 | __c: function(methodName) { 63 | var slf = this 64 | 65 | if (slf instanceof Boolean) { 66 | return function() { 67 | return false 68 | } 69 | } 70 | if (slf[methodName]) { 71 | return slf[methodName].bind(slf); 72 | } 73 | 74 | if (!slf.__obj && !slf.__clsName) { 75 | throw new Error(slf + '.' + methodName + ' is undefined') 76 | } 77 | if (slf.__isSuper && slf.__clsName) { 78 | slf.__clsName = _OC_superClsName(slf.__obj.__realClsName ? slf.__obj.__realClsName: slf.__clsName); 79 | } 80 | var clsName = slf.__clsName 81 | if (clsName && _ocCls[clsName]) { 82 | var methodType = slf.__obj ? 'instMethods': 'clsMethods' 83 | if (_ocCls[clsName][methodType][methodName]) { 84 | slf.__isSuper = 0; 85 | return _ocCls[clsName][methodType][methodName].bind(slf) 86 | } 87 | 88 | if (slf.__obj && _ocCls[clsName]['props'][methodName]) { 89 | if (!slf.__ocProps) { 90 | var props = _OC_getCustomProps(slf.__obj) 91 | if (!props) { 92 | props = {} 93 | _OC_setCustomProps(slf.__obj, props) 94 | } 95 | slf.__ocProps = props; 96 | } 97 | var c = methodName.charCodeAt(3); 98 | if (methodName.length > 3 && methodName.substr(0,3) == 'set' && c >= 65 && c <= 90) { 99 | return function(val) { 100 | var propName = methodName[3].toLowerCase() + methodName.substr(4) 101 | slf.__ocProps[propName] = val 102 | } 103 | } else { 104 | return function(){ 105 | return slf.__ocProps[methodName] 106 | } 107 | } 108 | } 109 | } 110 | 111 | return function(){ 112 | var args = Array.prototype.slice.call(arguments) 113 | return _methodFunc(slf.__obj, slf.__clsName, methodName, args, slf.__isSuper) 114 | } 115 | }, 116 | 117 | super: function() { 118 | var slf = this 119 | if (slf.__obj) { 120 | slf.__obj.__realClsName = slf.__realClsName; 121 | } 122 | return {__obj: slf.__obj, __clsName: slf.__clsName, __isSuper: 1} 123 | }, 124 | 125 | performSelectorInOC: function() { 126 | var slf = this 127 | var args = Array.prototype.slice.call(arguments) 128 | return {__isPerformInOC:1, obj:slf.__obj, clsName:slf.__clsName, sel: args[0], args: args[1], cb: args[2]} 129 | }, 130 | 131 | performSelector: function() { 132 | var slf = this 133 | var args = Array.prototype.slice.call(arguments) 134 | return _methodFunc(slf.__obj, slf.__clsName, args[0], args.splice(1), slf.__isSuper, true) 135 | } 136 | } 137 | 138 | for (var method in _customMethods) { 139 | if (_customMethods.hasOwnProperty(method)) { 140 | Object.defineProperty(Object.prototype, method, {value: _customMethods[method], configurable:false, enumerable: false}) 141 | } 142 | } 143 | 144 | var _require = function(clsName) { 145 | if (!global[clsName]) { 146 | global[clsName] = { 147 | __clsName: clsName 148 | } 149 | } 150 | return global[clsName] 151 | } 152 | 153 | global.require = function(clsNames) { 154 | var lastRequire 155 | clsNames.split(',').forEach(function(clsName) { 156 | lastRequire = _require(clsName.trim()) 157 | }) 158 | return lastRequire 159 | } 160 | 161 | var _formatDefineMethods = function(methods, newMethods, realClsName) { 162 | for (var methodName in methods) { 163 | if (!(methods[methodName] instanceof Function)) return; 164 | (function(){ 165 | var originMethod = methods[methodName] 166 | newMethods[methodName] = [originMethod.length, function() { 167 | try { 168 | var args = _formatOCToJS(Array.prototype.slice.call(arguments)) 169 | var lastSelf = global.self 170 | global.self = args[0] 171 | if (global.self) global.self.__realClsName = realClsName 172 | args.splice(0,1) 173 | var ret = originMethod.apply(originMethod, args) 174 | global.self = lastSelf 175 | return ret 176 | } catch(e) { 177 | _OC_catch(e.message, e.stack) 178 | } 179 | }] 180 | })() 181 | } 182 | } 183 | 184 | var _wrapLocalMethod = function(methodName, func, realClsName) { 185 | return function() { 186 | var lastSelf = global.self 187 | global.self = this 188 | this.__realClsName = realClsName 189 | var ret = func.apply(this, arguments) 190 | global.self = lastSelf 191 | return ret 192 | } 193 | } 194 | 195 | var _setupJSMethod = function(className, methods, isInst, realClsName) { 196 | for (var name in methods) { 197 | var key = isInst ? 'instMethods': 'clsMethods', 198 | func = methods[name] 199 | _ocCls[className][key][name] = _wrapLocalMethod(name, func, realClsName) 200 | } 201 | } 202 | 203 | global.defineClass = function(declaration, properties, instMethods, clsMethods) { 204 | var newInstMethods = {}, newClsMethods = {} 205 | if (!(properties instanceof Array)) { 206 | clsMethods = instMethods 207 | instMethods = properties 208 | properties = null 209 | } 210 | 211 | var realClsName = declaration.split(':')[0].trim() 212 | 213 | _formatDefineMethods(instMethods, newInstMethods, realClsName) 214 | _formatDefineMethods(clsMethods, newClsMethods, realClsName) 215 | 216 | var ret = _OC_defineClass(declaration, newInstMethods, newClsMethods) 217 | var className = ret['cls'] 218 | var superCls = ret['superCls'] 219 | 220 | _ocCls[className] = { 221 | instMethods: {}, 222 | clsMethods: {}, 223 | props: {} 224 | } 225 | 226 | if (superCls.length && _ocCls[superCls]) { 227 | for (var funcName in _ocCls[superCls]['instMethods']) { 228 | _ocCls[className]['instMethods'][funcName] = _ocCls[superCls]['instMethods'][funcName] 229 | } 230 | for (var funcName in _ocCls[superCls]['clsMethods']) { 231 | _ocCls[className]['clsMethods'][funcName] = _ocCls[superCls]['clsMethods'][funcName] 232 | } 233 | if (_ocCls[superCls]['props']) { 234 | _ocCls[className]['props'] = JSON.parse(JSON.stringify(_ocCls[superCls]['props'])); 235 | } 236 | } 237 | 238 | _setupJSMethod(className, instMethods, 1, realClsName) 239 | _setupJSMethod(className, clsMethods, 0, realClsName) 240 | 241 | if (properties) { 242 | properties.forEach(function(o){ 243 | _ocCls[className]['props'][o] = 1 244 | _ocCls[className]['props']['set' + o.substr(0,1).toUpperCase() + o.substr(1)] = 1 245 | }) 246 | } 247 | return require(className) 248 | } 249 | 250 | global.defineProtocol = function(declaration, instProtos , clsProtos) { 251 | var ret = _OC_defineProtocol(declaration, instProtos,clsProtos); 252 | return ret 253 | } 254 | 255 | global.block = function(args, cb) { 256 | var slf = this 257 | if (args instanceof Function) { 258 | cb = args 259 | args = '' 260 | } 261 | var callback = function() { 262 | var args = Array.prototype.slice.call(arguments) 263 | return cb.apply(slf, _formatOCToJS(args)) 264 | } 265 | return {args: args, cb: callback, __isBlock: 1} 266 | } 267 | 268 | if (global.console) { 269 | var jsLogger = console.log; 270 | global.console.log = function() { 271 | global._OC_log.apply(global, arguments); 272 | if (jsLogger) { 273 | jsLogger.apply(global.console, arguments); 274 | } 275 | } 276 | } else { 277 | global.console = { 278 | log: global._OC_log 279 | } 280 | } 281 | 282 | global.defineJSClass = function(declaration, instMethods, clsMethods) { 283 | var o = function() {}, 284 | a = declaration.split(':'), 285 | clsName = a[0].trim(), 286 | superClsName = a[1] ? a[1].trim() : null 287 | o.prototype = { 288 | init: function() { 289 | if (this.super()) this.super().init() 290 | return this; 291 | }, 292 | super: function() { 293 | return superClsName ? _jsCls[superClsName].prototype : null 294 | } 295 | } 296 | var cls = { 297 | alloc: function() { 298 | return new o; 299 | } 300 | } 301 | for (var methodName in instMethods) { 302 | o.prototype[methodName] = instMethods[methodName]; 303 | } 304 | for (var methodName in clsMethods) { 305 | cls[methodName] = clsMethods[methodName]; 306 | } 307 | global[clsName] = cls 308 | _jsCls[clsName] = o 309 | } 310 | 311 | global.YES = 1 312 | global.NO = 0 313 | global.nsnull = _OC_null 314 | global._formatOCToJS = _formatOCToJS 315 | 316 | })() -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0B81F2320589DB68CFB98E3E13EB72FF /* Pods-ScreenRecoderForGame-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D29F07BE24574472BFA6D7856CFB694B /* Pods-ScreenRecoderForGame-dummy.m */; }; 11 | 6371AF01D6F66B6A45C901711DB2419F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; }; 12 | 95B78BFC3D921957F8DD6A2CE3E0B499 /* JPEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = F1EDA88783649AD8FF7C2D4EBF520AB9 /* JPEngine.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | A04E758C13909C88410FA82419696F6D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; }; 14 | A7B8ECCAD3285C571FFAE1F87156FBF2 /* JSPatch-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C44F738DF2E0C195E73393800710490F /* JSPatch-dummy.m */; }; 15 | E90FE89EDA2F001944637A7C456AF004 /* JPEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BCA8D1AB7C36BC2BA27574126A0B1C1 /* JPEngine.m */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXContainerItemProxy section */ 19 | CE3EA6740786F9ECB104FD2E855FD075 /* PBXContainerItemProxy */ = { 20 | isa = PBXContainerItemProxy; 21 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 22 | proxyType = 1; 23 | remoteGlobalIDString = FD1D53461DE538B7C8DFE0B76D857587; 24 | remoteInfo = JSPatch; 25 | }; 26 | /* End PBXContainerItemProxy section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 15E3F44D6C7E78CCCDB3C1E292A0701E /* JSPatch-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JSPatch-prefix.pch"; sourceTree = ""; }; 30 | 300878CB3EA3C495E607D4CE0DC85CDB /* libPods-ScreenRecoderForGame.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScreenRecoderForGame.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 32 | 490E4836CB83394A7899C98DCC56C1D0 /* Pods-ScreenRecoderForGame.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ScreenRecoderForGame.debug.xcconfig"; sourceTree = ""; }; 33 | 591E7937CE0B1BA39CA85CA5F6FCEA58 /* Pods-ScreenRecoderForGame-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ScreenRecoderForGame-frameworks.sh"; sourceTree = ""; }; 34 | 5DDE5A2F5FEF0C06EF2AC8151472490F /* JSPatch.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JSPatch.xcconfig; sourceTree = ""; }; 35 | 7BCA8D1AB7C36BC2BA27574126A0B1C1 /* JPEngine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = JPEngine.m; path = JSPatch/JPEngine.m; sourceTree = ""; }; 36 | 9102475FCD6EA8C6AF5F9AB0BCAF155C /* Pods-ScreenRecoderForGame-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ScreenRecoderForGame-resources.sh"; sourceTree = ""; }; 37 | 9F6DDFDDAB8EB8406FEA618B614FE274 /* libJSPatch.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libJSPatch.a; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | A586D1929F1BC22B3A54870EE2C94471 /* Pods-ScreenRecoderForGame-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ScreenRecoderForGame-acknowledgements.markdown"; sourceTree = ""; }; 39 | BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 40 | C44F738DF2E0C195E73393800710490F /* JSPatch-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "JSPatch-dummy.m"; sourceTree = ""; }; 41 | C93A2C60F9576FF6FFB43028673ED931 /* JSPatch.js */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.javascript; name = JSPatch.js; path = JSPatch/JSPatch.js; sourceTree = ""; }; 42 | D29F07BE24574472BFA6D7856CFB694B /* Pods-ScreenRecoderForGame-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ScreenRecoderForGame-dummy.m"; sourceTree = ""; }; 43 | D32B0A49EE6067C11281269426C73F13 /* Pods-ScreenRecoderForGame.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ScreenRecoderForGame.release.xcconfig"; sourceTree = ""; }; 44 | F1EDA88783649AD8FF7C2D4EBF520AB9 /* JPEngine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JPEngine.h; path = JSPatch/JPEngine.h; sourceTree = ""; }; 45 | FE96BB0834EAFFBF6458F60F372966A5 /* Pods-ScreenRecoderForGame-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ScreenRecoderForGame-acknowledgements.plist"; sourceTree = ""; }; 46 | /* End PBXFileReference section */ 47 | 48 | /* Begin PBXFrameworksBuildPhase section */ 49 | 00CD0B0096519208337740D5BC28FE6D /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | 6371AF01D6F66B6A45C901711DB2419F /* Foundation.framework in Frameworks */, 54 | ); 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | 1C59F081ABC207547FC2084D7FEC1F6A /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | A04E758C13909C88410FA82419696F6D /* Foundation.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 12F600937FD28AD7E2D1DE4A14CBDFC8 /* Core */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | F1EDA88783649AD8FF7C2D4EBF520AB9 /* JPEngine.h */, 72 | 7BCA8D1AB7C36BC2BA27574126A0B1C1 /* JPEngine.m */, 73 | 8607D1593C34FC5744A76E796B1B8748 /* Resources */, 74 | ); 75 | name = Core; 76 | sourceTree = ""; 77 | }; 78 | 3C8578D693A3AEA8175F28C8A14349A3 /* Pods-ScreenRecoderForGame */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | A586D1929F1BC22B3A54870EE2C94471 /* Pods-ScreenRecoderForGame-acknowledgements.markdown */, 82 | FE96BB0834EAFFBF6458F60F372966A5 /* Pods-ScreenRecoderForGame-acknowledgements.plist */, 83 | D29F07BE24574472BFA6D7856CFB694B /* Pods-ScreenRecoderForGame-dummy.m */, 84 | 591E7937CE0B1BA39CA85CA5F6FCEA58 /* Pods-ScreenRecoderForGame-frameworks.sh */, 85 | 9102475FCD6EA8C6AF5F9AB0BCAF155C /* Pods-ScreenRecoderForGame-resources.sh */, 86 | 490E4836CB83394A7899C98DCC56C1D0 /* Pods-ScreenRecoderForGame.debug.xcconfig */, 87 | D32B0A49EE6067C11281269426C73F13 /* Pods-ScreenRecoderForGame.release.xcconfig */, 88 | ); 89 | name = "Pods-ScreenRecoderForGame"; 90 | path = "Target Support Files/Pods-ScreenRecoderForGame"; 91 | sourceTree = ""; 92 | }; 93 | 6625EA184C420D28881C9EF98A6E3122 /* Products */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 9F6DDFDDAB8EB8406FEA618B614FE274 /* libJSPatch.a */, 97 | 300878CB3EA3C495E607D4CE0DC85CDB /* libPods-ScreenRecoderForGame.a */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | 7DB346D0F39D3F0E887471402A8071AB = { 103 | isa = PBXGroup; 104 | children = ( 105 | BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */, 106 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, 107 | FD71C87333830EEE381B5639A0CADE7B /* Pods */, 108 | 6625EA184C420D28881C9EF98A6E3122 /* Products */, 109 | D738051DAA46DE18212F6636BC8D42B5 /* Targets Support Files */, 110 | ); 111 | sourceTree = ""; 112 | }; 113 | 8607D1593C34FC5744A76E796B1B8748 /* Resources */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | C93A2C60F9576FF6FFB43028673ED931 /* JSPatch.js */, 117 | ); 118 | name = Resources; 119 | sourceTree = ""; 120 | }; 121 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | BF6342C8B29F4CEEA088EFF7AB4DE362 /* iOS */, 125 | ); 126 | name = Frameworks; 127 | sourceTree = ""; 128 | }; 129 | BF6342C8B29F4CEEA088EFF7AB4DE362 /* iOS */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */, 133 | ); 134 | name = iOS; 135 | sourceTree = ""; 136 | }; 137 | C5EE343E5EDEE603734BB277436D2AC0 /* Support Files */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 5DDE5A2F5FEF0C06EF2AC8151472490F /* JSPatch.xcconfig */, 141 | C44F738DF2E0C195E73393800710490F /* JSPatch-dummy.m */, 142 | 15E3F44D6C7E78CCCDB3C1E292A0701E /* JSPatch-prefix.pch */, 143 | ); 144 | name = "Support Files"; 145 | path = "../Target Support Files/JSPatch"; 146 | sourceTree = ""; 147 | }; 148 | D738051DAA46DE18212F6636BC8D42B5 /* Targets Support Files */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 3C8578D693A3AEA8175F28C8A14349A3 /* Pods-ScreenRecoderForGame */, 152 | ); 153 | name = "Targets Support Files"; 154 | sourceTree = ""; 155 | }; 156 | EBAFF95D47A3AEBE347C34AA377CBC5D /* JSPatch */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 12F600937FD28AD7E2D1DE4A14CBDFC8 /* Core */, 160 | C5EE343E5EDEE603734BB277436D2AC0 /* Support Files */, 161 | ); 162 | path = JSPatch; 163 | sourceTree = ""; 164 | }; 165 | FD71C87333830EEE381B5639A0CADE7B /* Pods */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | EBAFF95D47A3AEBE347C34AA377CBC5D /* JSPatch */, 169 | ); 170 | name = Pods; 171 | sourceTree = ""; 172 | }; 173 | /* End PBXGroup section */ 174 | 175 | /* Begin PBXHeadersBuildPhase section */ 176 | EC0D5F87286AE5412CAC701D6ACAB402 /* Headers */ = { 177 | isa = PBXHeadersBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | 95B78BFC3D921957F8DD6A2CE3E0B499 /* JPEngine.h in Headers */, 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | }; 184 | /* End PBXHeadersBuildPhase section */ 185 | 186 | /* Begin PBXNativeTarget section */ 187 | D0BC7E6EFC582F02D2B5AD0B867A7FC9 /* Pods-ScreenRecoderForGame */ = { 188 | isa = PBXNativeTarget; 189 | buildConfigurationList = B71EACE05097B11A52339AF8C49F7A1E /* Build configuration list for PBXNativeTarget "Pods-ScreenRecoderForGame" */; 190 | buildPhases = ( 191 | B3FA8B92DC0EE45964E0B9CC4F4C2CEC /* Sources */, 192 | 1C59F081ABC207547FC2084D7FEC1F6A /* Frameworks */, 193 | ); 194 | buildRules = ( 195 | ); 196 | dependencies = ( 197 | E6EF983ECDDDBCA289D45B87452C22BD /* PBXTargetDependency */, 198 | ); 199 | name = "Pods-ScreenRecoderForGame"; 200 | productName = "Pods-ScreenRecoderForGame"; 201 | productReference = 300878CB3EA3C495E607D4CE0DC85CDB /* libPods-ScreenRecoderForGame.a */; 202 | productType = "com.apple.product-type.library.static"; 203 | }; 204 | FD1D53461DE538B7C8DFE0B76D857587 /* JSPatch */ = { 205 | isa = PBXNativeTarget; 206 | buildConfigurationList = D6237EEAE81FAC77DC4CDAA075B264E9 /* Build configuration list for PBXNativeTarget "JSPatch" */; 207 | buildPhases = ( 208 | 7F85DFA0BA8E5DF5155BF3912A24B2A0 /* Sources */, 209 | 00CD0B0096519208337740D5BC28FE6D /* Frameworks */, 210 | EC0D5F87286AE5412CAC701D6ACAB402 /* Headers */, 211 | ); 212 | buildRules = ( 213 | ); 214 | dependencies = ( 215 | ); 216 | name = JSPatch; 217 | productName = JSPatch; 218 | productReference = 9F6DDFDDAB8EB8406FEA618B614FE274 /* libJSPatch.a */; 219 | productType = "com.apple.product-type.library.static"; 220 | }; 221 | /* End PBXNativeTarget section */ 222 | 223 | /* Begin PBXProject section */ 224 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 225 | isa = PBXProject; 226 | attributes = { 227 | LastSwiftUpdateCheck = 0700; 228 | LastUpgradeCheck = 0700; 229 | }; 230 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 231 | compatibilityVersion = "Xcode 3.2"; 232 | developmentRegion = English; 233 | hasScannedForEncodings = 0; 234 | knownRegions = ( 235 | en, 236 | ); 237 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 238 | productRefGroup = 6625EA184C420D28881C9EF98A6E3122 /* Products */; 239 | projectDirPath = ""; 240 | projectRoot = ""; 241 | targets = ( 242 | FD1D53461DE538B7C8DFE0B76D857587 /* JSPatch */, 243 | D0BC7E6EFC582F02D2B5AD0B867A7FC9 /* Pods-ScreenRecoderForGame */, 244 | ); 245 | }; 246 | /* End PBXProject section */ 247 | 248 | /* Begin PBXSourcesBuildPhase section */ 249 | 7F85DFA0BA8E5DF5155BF3912A24B2A0 /* Sources */ = { 250 | isa = PBXSourcesBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | E90FE89EDA2F001944637A7C456AF004 /* JPEngine.m in Sources */, 254 | A7B8ECCAD3285C571FFAE1F87156FBF2 /* JSPatch-dummy.m in Sources */, 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | B3FA8B92DC0EE45964E0B9CC4F4C2CEC /* Sources */ = { 259 | isa = PBXSourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 0B81F2320589DB68CFB98E3E13EB72FF /* Pods-ScreenRecoderForGame-dummy.m in Sources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXSourcesBuildPhase section */ 267 | 268 | /* Begin PBXTargetDependency section */ 269 | E6EF983ECDDDBCA289D45B87452C22BD /* PBXTargetDependency */ = { 270 | isa = PBXTargetDependency; 271 | name = JSPatch; 272 | target = FD1D53461DE538B7C8DFE0B76D857587 /* JSPatch */; 273 | targetProxy = CE3EA6740786F9ECB104FD2E855FD075 /* PBXContainerItemProxy */; 274 | }; 275 | /* End PBXTargetDependency section */ 276 | 277 | /* Begin XCBuildConfiguration section */ 278 | 14268068F2ECF0BFF372C12220DAA59F /* Debug */ = { 279 | isa = XCBuildConfiguration; 280 | baseConfigurationReference = 490E4836CB83394A7899C98DCC56C1D0 /* Pods-ScreenRecoderForGame.debug.xcconfig */; 281 | buildSettings = { 282 | ENABLE_STRICT_OBJC_MSGSEND = YES; 283 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 284 | MACH_O_TYPE = staticlib; 285 | MTL_ENABLE_DEBUG_INFO = YES; 286 | OTHER_LDFLAGS = ""; 287 | OTHER_LIBTOOLFLAGS = ""; 288 | PODS_ROOT = "$(SRCROOT)"; 289 | PRODUCT_NAME = "$(TARGET_NAME)"; 290 | SDKROOT = iphoneos; 291 | SKIP_INSTALL = YES; 292 | }; 293 | name = Debug; 294 | }; 295 | 2F6972ADBC5C10F0DB7BFADA1BCBBE6A /* Debug */ = { 296 | isa = XCBuildConfiguration; 297 | baseConfigurationReference = 5DDE5A2F5FEF0C06EF2AC8151472490F /* JSPatch.xcconfig */; 298 | buildSettings = { 299 | ENABLE_STRICT_OBJC_MSGSEND = YES; 300 | GCC_PREFIX_HEADER = "Target Support Files/JSPatch/JSPatch-prefix.pch"; 301 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 302 | MTL_ENABLE_DEBUG_INFO = YES; 303 | OTHER_LDFLAGS = ""; 304 | OTHER_LIBTOOLFLAGS = ""; 305 | PRIVATE_HEADERS_FOLDER_PATH = ""; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | PUBLIC_HEADERS_FOLDER_PATH = ""; 308 | SDKROOT = iphoneos; 309 | SKIP_INSTALL = YES; 310 | }; 311 | name = Debug; 312 | }; 313 | 5CE5176205D06FF3FFE3DDDA9291E44B /* Debug */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 318 | CLANG_CXX_LIBRARY = "libc++"; 319 | CLANG_ENABLE_MODULES = YES; 320 | CLANG_ENABLE_OBJC_ARC = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_INT_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | COPY_PHASE_STRIP = NO; 331 | GCC_C_LANGUAGE_STANDARD = gnu99; 332 | GCC_DYNAMIC_NO_PIC = NO; 333 | GCC_OPTIMIZATION_LEVEL = 0; 334 | GCC_PREPROCESSOR_DEFINITIONS = ( 335 | "DEBUG=1", 336 | "$(inherited)", 337 | ); 338 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 339 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 340 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 341 | GCC_WARN_UNDECLARED_SELECTOR = YES; 342 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 343 | GCC_WARN_UNUSED_FUNCTION = YES; 344 | GCC_WARN_UNUSED_VARIABLE = YES; 345 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 346 | ONLY_ACTIVE_ARCH = YES; 347 | STRIP_INSTALLED_PRODUCT = NO; 348 | SYMROOT = "${SRCROOT}/../build"; 349 | }; 350 | name = Debug; 351 | }; 352 | 6C351FDDC3B2149FCE3D633F2D21579A /* Release */ = { 353 | isa = XCBuildConfiguration; 354 | baseConfigurationReference = D32B0A49EE6067C11281269426C73F13 /* Pods-ScreenRecoderForGame.release.xcconfig */; 355 | buildSettings = { 356 | ENABLE_STRICT_OBJC_MSGSEND = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 358 | MACH_O_TYPE = staticlib; 359 | MTL_ENABLE_DEBUG_INFO = NO; 360 | OTHER_LDFLAGS = ""; 361 | OTHER_LIBTOOLFLAGS = ""; 362 | PODS_ROOT = "$(SRCROOT)"; 363 | PRODUCT_NAME = "$(TARGET_NAME)"; 364 | SDKROOT = iphoneos; 365 | SKIP_INSTALL = YES; 366 | }; 367 | name = Release; 368 | }; 369 | 74857149DC1E0D599B8A01A78349A926 /* Release */ = { 370 | isa = XCBuildConfiguration; 371 | buildSettings = { 372 | ALWAYS_SEARCH_USER_PATHS = NO; 373 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 374 | CLANG_CXX_LIBRARY = "libc++"; 375 | CLANG_ENABLE_MODULES = YES; 376 | CLANG_ENABLE_OBJC_ARC = YES; 377 | CLANG_WARN_BOOL_CONVERSION = YES; 378 | CLANG_WARN_CONSTANT_CONVERSION = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 380 | CLANG_WARN_EMPTY_BODY = YES; 381 | CLANG_WARN_ENUM_CONVERSION = YES; 382 | CLANG_WARN_INT_CONVERSION = YES; 383 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 384 | CLANG_WARN_UNREACHABLE_CODE = YES; 385 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 386 | COPY_PHASE_STRIP = YES; 387 | ENABLE_NS_ASSERTIONS = NO; 388 | GCC_C_LANGUAGE_STANDARD = gnu99; 389 | GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1"; 390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 391 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 392 | GCC_WARN_UNDECLARED_SELECTOR = YES; 393 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 397 | STRIP_INSTALLED_PRODUCT = NO; 398 | SYMROOT = "${SRCROOT}/../build"; 399 | VALIDATE_PRODUCT = YES; 400 | }; 401 | name = Release; 402 | }; 403 | AECE5ABDFC9F363CB6B0A03A8DBEBB0F /* Release */ = { 404 | isa = XCBuildConfiguration; 405 | baseConfigurationReference = 5DDE5A2F5FEF0C06EF2AC8151472490F /* JSPatch.xcconfig */; 406 | buildSettings = { 407 | ENABLE_STRICT_OBJC_MSGSEND = YES; 408 | GCC_PREFIX_HEADER = "Target Support Files/JSPatch/JSPatch-prefix.pch"; 409 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 410 | MTL_ENABLE_DEBUG_INFO = NO; 411 | OTHER_LDFLAGS = ""; 412 | OTHER_LIBTOOLFLAGS = ""; 413 | PRIVATE_HEADERS_FOLDER_PATH = ""; 414 | PRODUCT_NAME = "$(TARGET_NAME)"; 415 | PUBLIC_HEADERS_FOLDER_PATH = ""; 416 | SDKROOT = iphoneos; 417 | SKIP_INSTALL = YES; 418 | }; 419 | name = Release; 420 | }; 421 | /* End XCBuildConfiguration section */ 422 | 423 | /* Begin XCConfigurationList section */ 424 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 425 | isa = XCConfigurationList; 426 | buildConfigurations = ( 427 | 5CE5176205D06FF3FFE3DDDA9291E44B /* Debug */, 428 | 74857149DC1E0D599B8A01A78349A926 /* Release */, 429 | ); 430 | defaultConfigurationIsVisible = 0; 431 | defaultConfigurationName = Release; 432 | }; 433 | B71EACE05097B11A52339AF8C49F7A1E /* Build configuration list for PBXNativeTarget "Pods-ScreenRecoderForGame" */ = { 434 | isa = XCConfigurationList; 435 | buildConfigurations = ( 436 | 14268068F2ECF0BFF372C12220DAA59F /* Debug */, 437 | 6C351FDDC3B2149FCE3D633F2D21579A /* Release */, 438 | ); 439 | defaultConfigurationIsVisible = 0; 440 | defaultConfigurationName = Release; 441 | }; 442 | D6237EEAE81FAC77DC4CDAA075B264E9 /* Build configuration list for PBXNativeTarget "JSPatch" */ = { 443 | isa = XCConfigurationList; 444 | buildConfigurations = ( 445 | 2F6972ADBC5C10F0DB7BFADA1BCBBE6A /* Debug */, 446 | AECE5ABDFC9F363CB6B0A03A8DBEBB0F /* Release */, 447 | ); 448 | defaultConfigurationIsVisible = 0; 449 | defaultConfigurationName = Release; 450 | }; 451 | /* End XCConfigurationList section */ 452 | }; 453 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 454 | } 455 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/ScreenRecoderForGame.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4765DC75644BDE0E2BCF5599 /* libPods-ScreenRecoderForGame.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 168EC6C7E2FF8B11A1CB8E30 /* libPods-ScreenRecoderForGame.a */; }; 11 | FCFA52E71CC8CB0400EB6FC2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA52E61CC8CB0400EB6FC2 /* main.m */; }; 12 | FCFA52EA1CC8CB0400EB6FC2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA52E91CC8CB0400EB6FC2 /* AppDelegate.m */; }; 13 | FCFA52ED1CC8CB0400EB6FC2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA52EC1CC8CB0400EB6FC2 /* ViewController.m */; }; 14 | FCFA52F01CC8CB0400EB6FC2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FCFA52EE1CC8CB0400EB6FC2 /* Main.storyboard */; }; 15 | FCFA52F21CC8CB0400EB6FC2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FCFA52F11CC8CB0400EB6FC2 /* Assets.xcassets */; }; 16 | FCFA52F51CC8CB0400EB6FC2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FCFA52F31CC8CB0400EB6FC2 /* LaunchScreen.storyboard */; }; 17 | FCFA53001CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA52FF1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.m */; }; 18 | FCFA530B1CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA530A1CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.m */; }; 19 | FCFA53191CC8CB8A00EB6FC2 /* a.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = FCFA53181CC8CB8A00EB6FC2 /* a.mp3 */; }; 20 | FCFA531D1CC8CBD600EB6FC2 /* GameScreenRecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA531C1CC8CBD600EB6FC2 /* GameScreenRecoder.m */; }; 21 | FCFA53211CC8CC5100EB6FC2 /* 0.png in Resources */ = {isa = PBXBuildFile; fileRef = FCFA53201CC8CC5100EB6FC2 /* 0.png */; }; 22 | FCFA53231CC8D31D00EB6FC2 /* 1.gif in Resources */ = {isa = PBXBuildFile; fileRef = FCFA53221CC8D31D00EB6FC2 /* 1.gif */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | FCFA52FC1CC8CB0400EB6FC2 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = FCFA52DA1CC8CB0400EB6FC2 /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = FCFA52E11CC8CB0400EB6FC2; 31 | remoteInfo = ScreenRecoderForGame; 32 | }; 33 | FCFA53071CC8CB0400EB6FC2 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = FCFA52DA1CC8CB0400EB6FC2 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = FCFA52E11CC8CB0400EB6FC2; 38 | remoteInfo = ScreenRecoderForGame; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 168EC6C7E2FF8B11A1CB8E30 /* libPods-ScreenRecoderForGame.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScreenRecoderForGame.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 72E00202D3F9EE37184F377D /* Pods-ScreenRecoderForGame.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenRecoderForGame.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame.debug.xcconfig"; sourceTree = ""; }; 45 | AE86827476DDF9FAE91B1F7C /* Pods-ScreenRecoderForGame.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenRecoderForGame.release.xcconfig"; path = "Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame.release.xcconfig"; sourceTree = ""; }; 46 | FCFA52E21CC8CB0400EB6FC2 /* ScreenRecoderForGame.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScreenRecoderForGame.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | FCFA52E61CC8CB0400EB6FC2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 48 | FCFA52E81CC8CB0400EB6FC2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 49 | FCFA52E91CC8CB0400EB6FC2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 50 | FCFA52EB1CC8CB0400EB6FC2 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 51 | FCFA52EC1CC8CB0400EB6FC2 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 52 | FCFA52EF1CC8CB0400EB6FC2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 53 | FCFA52F11CC8CB0400EB6FC2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54 | FCFA52F41CC8CB0400EB6FC2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 55 | FCFA52F61CC8CB0400EB6FC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | FCFA52FB1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreenRecoderForGameTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | FCFA52FF1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScreenRecoderForGameTests.m; sourceTree = ""; }; 58 | FCFA53011CC8CB0400EB6FC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | FCFA53061CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreenRecoderForGameUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | FCFA530A1CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScreenRecoderForGameUITests.m; sourceTree = ""; }; 61 | FCFA530C1CC8CB0400EB6FC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 62 | FCFA53181CC8CB8A00EB6FC2 /* a.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = a.mp3; sourceTree = ""; }; 63 | FCFA531B1CC8CBD600EB6FC2 /* GameScreenRecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameScreenRecoder.h; sourceTree = ""; }; 64 | FCFA531C1CC8CBD600EB6FC2 /* GameScreenRecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GameScreenRecoder.m; sourceTree = ""; }; 65 | FCFA53201CC8CC5100EB6FC2 /* 0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 0.png; sourceTree = ""; }; 66 | FCFA53221CC8D31D00EB6FC2 /* 1.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = 1.gif; sourceTree = ""; }; 67 | /* End PBXFileReference section */ 68 | 69 | /* Begin PBXFrameworksBuildPhase section */ 70 | FCFA52DF1CC8CB0400EB6FC2 /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | 4765DC75644BDE0E2BCF5599 /* libPods-ScreenRecoderForGame.a in Frameworks */, 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | FCFA52F81CC8CB0400EB6FC2 /* Frameworks */ = { 79 | isa = PBXFrameworksBuildPhase; 80 | buildActionMask = 2147483647; 81 | files = ( 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | FCFA53031CC8CB0400EB6FC2 /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | /* End PBXFrameworksBuildPhase section */ 93 | 94 | /* Begin PBXGroup section */ 95 | C19641688CBEEB92981F6F64 /* Frameworks */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 168EC6C7E2FF8B11A1CB8E30 /* libPods-ScreenRecoderForGame.a */, 99 | ); 100 | name = Frameworks; 101 | sourceTree = ""; 102 | }; 103 | DA274E95A2A86AF65ED94911 /* Pods */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 72E00202D3F9EE37184F377D /* Pods-ScreenRecoderForGame.debug.xcconfig */, 107 | AE86827476DDF9FAE91B1F7C /* Pods-ScreenRecoderForGame.release.xcconfig */, 108 | ); 109 | name = Pods; 110 | sourceTree = ""; 111 | }; 112 | FCFA52D91CC8CB0400EB6FC2 = { 113 | isa = PBXGroup; 114 | children = ( 115 | FCFA531A1CC8CBA500EB6FC2 /* Recoder */, 116 | FCFA52E41CC8CB0400EB6FC2 /* ScreenRecoderForGame */, 117 | FCFA52FE1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests */, 118 | FCFA53091CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests */, 119 | FCFA52E31CC8CB0400EB6FC2 /* Products */, 120 | DA274E95A2A86AF65ED94911 /* Pods */, 121 | C19641688CBEEB92981F6F64 /* Frameworks */, 122 | ); 123 | sourceTree = ""; 124 | }; 125 | FCFA52E31CC8CB0400EB6FC2 /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | FCFA52E21CC8CB0400EB6FC2 /* ScreenRecoderForGame.app */, 129 | FCFA52FB1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.xctest */, 130 | FCFA53061CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.xctest */, 131 | ); 132 | name = Products; 133 | sourceTree = ""; 134 | }; 135 | FCFA52E41CC8CB0400EB6FC2 /* ScreenRecoderForGame */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | FCFA52E81CC8CB0400EB6FC2 /* AppDelegate.h */, 139 | FCFA52E91CC8CB0400EB6FC2 /* AppDelegate.m */, 140 | FCFA52EB1CC8CB0400EB6FC2 /* ViewController.h */, 141 | FCFA52EC1CC8CB0400EB6FC2 /* ViewController.m */, 142 | FCFA52EE1CC8CB0400EB6FC2 /* Main.storyboard */, 143 | FCFA52F11CC8CB0400EB6FC2 /* Assets.xcassets */, 144 | FCFA52F31CC8CB0400EB6FC2 /* LaunchScreen.storyboard */, 145 | FCFA52F61CC8CB0400EB6FC2 /* Info.plist */, 146 | FCFA52E51CC8CB0400EB6FC2 /* Supporting Files */, 147 | ); 148 | path = ScreenRecoderForGame; 149 | sourceTree = ""; 150 | }; 151 | FCFA52E51CC8CB0400EB6FC2 /* Supporting Files */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | FCFA53221CC8D31D00EB6FC2 /* 1.gif */, 155 | FCFA53201CC8CC5100EB6FC2 /* 0.png */, 156 | FCFA53181CC8CB8A00EB6FC2 /* a.mp3 */, 157 | FCFA52E61CC8CB0400EB6FC2 /* main.m */, 158 | ); 159 | name = "Supporting Files"; 160 | sourceTree = ""; 161 | }; 162 | FCFA52FE1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | FCFA52FF1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.m */, 166 | FCFA53011CC8CB0400EB6FC2 /* Info.plist */, 167 | ); 168 | path = ScreenRecoderForGameTests; 169 | sourceTree = ""; 170 | }; 171 | FCFA53091CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | FCFA530A1CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.m */, 175 | FCFA530C1CC8CB0400EB6FC2 /* Info.plist */, 176 | ); 177 | path = ScreenRecoderForGameUITests; 178 | sourceTree = ""; 179 | }; 180 | FCFA531A1CC8CBA500EB6FC2 /* Recoder */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | FCFA531B1CC8CBD600EB6FC2 /* GameScreenRecoder.h */, 184 | FCFA531C1CC8CBD600EB6FC2 /* GameScreenRecoder.m */, 185 | ); 186 | name = Recoder; 187 | sourceTree = ""; 188 | }; 189 | /* End PBXGroup section */ 190 | 191 | /* Begin PBXNativeTarget section */ 192 | FCFA52E11CC8CB0400EB6FC2 /* ScreenRecoderForGame */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = FCFA530F1CC8CB0400EB6FC2 /* Build configuration list for PBXNativeTarget "ScreenRecoderForGame" */; 195 | buildPhases = ( 196 | 773F149D54CB0FA79A09E75A /* Check Pods Manifest.lock */, 197 | FCFA52DE1CC8CB0400EB6FC2 /* Sources */, 198 | FCFA52DF1CC8CB0400EB6FC2 /* Frameworks */, 199 | FCFA52E01CC8CB0400EB6FC2 /* Resources */, 200 | 5AAD30359772AB3A51690EC6 /* Embed Pods Frameworks */, 201 | 38FA2308FE7328452FC7F00A /* Copy Pods Resources */, 202 | ); 203 | buildRules = ( 204 | ); 205 | dependencies = ( 206 | ); 207 | name = ScreenRecoderForGame; 208 | productName = ScreenRecoderForGame; 209 | productReference = FCFA52E21CC8CB0400EB6FC2 /* ScreenRecoderForGame.app */; 210 | productType = "com.apple.product-type.application"; 211 | }; 212 | FCFA52FA1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests */ = { 213 | isa = PBXNativeTarget; 214 | buildConfigurationList = FCFA53121CC8CB0400EB6FC2 /* Build configuration list for PBXNativeTarget "ScreenRecoderForGameTests" */; 215 | buildPhases = ( 216 | FCFA52F71CC8CB0400EB6FC2 /* Sources */, 217 | FCFA52F81CC8CB0400EB6FC2 /* Frameworks */, 218 | FCFA52F91CC8CB0400EB6FC2 /* Resources */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | FCFA52FD1CC8CB0400EB6FC2 /* PBXTargetDependency */, 224 | ); 225 | name = ScreenRecoderForGameTests; 226 | productName = ScreenRecoderForGameTests; 227 | productReference = FCFA52FB1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.xctest */; 228 | productType = "com.apple.product-type.bundle.unit-test"; 229 | }; 230 | FCFA53051CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = FCFA53151CC8CB0400EB6FC2 /* Build configuration list for PBXNativeTarget "ScreenRecoderForGameUITests" */; 233 | buildPhases = ( 234 | FCFA53021CC8CB0400EB6FC2 /* Sources */, 235 | FCFA53031CC8CB0400EB6FC2 /* Frameworks */, 236 | FCFA53041CC8CB0400EB6FC2 /* Resources */, 237 | ); 238 | buildRules = ( 239 | ); 240 | dependencies = ( 241 | FCFA53081CC8CB0400EB6FC2 /* PBXTargetDependency */, 242 | ); 243 | name = ScreenRecoderForGameUITests; 244 | productName = ScreenRecoderForGameUITests; 245 | productReference = FCFA53061CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.xctest */; 246 | productType = "com.apple.product-type.bundle.ui-testing"; 247 | }; 248 | /* End PBXNativeTarget section */ 249 | 250 | /* Begin PBXProject section */ 251 | FCFA52DA1CC8CB0400EB6FC2 /* Project object */ = { 252 | isa = PBXProject; 253 | attributes = { 254 | LastUpgradeCheck = 0730; 255 | ORGANIZATIONNAME = qianwei; 256 | TargetAttributes = { 257 | FCFA52E11CC8CB0400EB6FC2 = { 258 | CreatedOnToolsVersion = 7.3; 259 | DevelopmentTeam = SSJK4DGTL7; 260 | }; 261 | FCFA52FA1CC8CB0400EB6FC2 = { 262 | CreatedOnToolsVersion = 7.3; 263 | DevelopmentTeam = SSJK4DGTL7; 264 | TestTargetID = FCFA52E11CC8CB0400EB6FC2; 265 | }; 266 | FCFA53051CC8CB0400EB6FC2 = { 267 | CreatedOnToolsVersion = 7.3; 268 | DevelopmentTeam = SSJK4DGTL7; 269 | TestTargetID = FCFA52E11CC8CB0400EB6FC2; 270 | }; 271 | }; 272 | }; 273 | buildConfigurationList = FCFA52DD1CC8CB0400EB6FC2 /* Build configuration list for PBXProject "ScreenRecoderForGame" */; 274 | compatibilityVersion = "Xcode 3.2"; 275 | developmentRegion = English; 276 | hasScannedForEncodings = 0; 277 | knownRegions = ( 278 | en, 279 | Base, 280 | ); 281 | mainGroup = FCFA52D91CC8CB0400EB6FC2; 282 | productRefGroup = FCFA52E31CC8CB0400EB6FC2 /* Products */; 283 | projectDirPath = ""; 284 | projectRoot = ""; 285 | targets = ( 286 | FCFA52E11CC8CB0400EB6FC2 /* ScreenRecoderForGame */, 287 | FCFA52FA1CC8CB0400EB6FC2 /* ScreenRecoderForGameTests */, 288 | FCFA53051CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests */, 289 | ); 290 | }; 291 | /* End PBXProject section */ 292 | 293 | /* Begin PBXResourcesBuildPhase section */ 294 | FCFA52E01CC8CB0400EB6FC2 /* Resources */ = { 295 | isa = PBXResourcesBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | FCFA53231CC8D31D00EB6FC2 /* 1.gif in Resources */, 299 | FCFA53211CC8CC5100EB6FC2 /* 0.png in Resources */, 300 | FCFA53191CC8CB8A00EB6FC2 /* a.mp3 in Resources */, 301 | FCFA52F51CC8CB0400EB6FC2 /* LaunchScreen.storyboard in Resources */, 302 | FCFA52F21CC8CB0400EB6FC2 /* Assets.xcassets in Resources */, 303 | FCFA52F01CC8CB0400EB6FC2 /* Main.storyboard in Resources */, 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | }; 307 | FCFA52F91CC8CB0400EB6FC2 /* Resources */ = { 308 | isa = PBXResourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | }; 314 | FCFA53041CC8CB0400EB6FC2 /* Resources */ = { 315 | isa = PBXResourcesBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | ); 319 | runOnlyForDeploymentPostprocessing = 0; 320 | }; 321 | /* End PBXResourcesBuildPhase section */ 322 | 323 | /* Begin PBXShellScriptBuildPhase section */ 324 | 38FA2308FE7328452FC7F00A /* Copy Pods Resources */ = { 325 | isa = PBXShellScriptBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | ); 329 | inputPaths = ( 330 | ); 331 | name = "Copy Pods Resources"; 332 | outputPaths = ( 333 | ); 334 | runOnlyForDeploymentPostprocessing = 0; 335 | shellPath = /bin/sh; 336 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame-resources.sh\"\n"; 337 | showEnvVarsInLog = 0; 338 | }; 339 | 5AAD30359772AB3A51690EC6 /* Embed Pods Frameworks */ = { 340 | isa = PBXShellScriptBuildPhase; 341 | buildActionMask = 2147483647; 342 | files = ( 343 | ); 344 | inputPaths = ( 345 | ); 346 | name = "Embed Pods Frameworks"; 347 | outputPaths = ( 348 | ); 349 | runOnlyForDeploymentPostprocessing = 0; 350 | shellPath = /bin/sh; 351 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ScreenRecoderForGame/Pods-ScreenRecoderForGame-frameworks.sh\"\n"; 352 | showEnvVarsInLog = 0; 353 | }; 354 | 773F149D54CB0FA79A09E75A /* Check Pods Manifest.lock */ = { 355 | isa = PBXShellScriptBuildPhase; 356 | buildActionMask = 2147483647; 357 | files = ( 358 | ); 359 | inputPaths = ( 360 | ); 361 | name = "Check Pods Manifest.lock"; 362 | outputPaths = ( 363 | ); 364 | runOnlyForDeploymentPostprocessing = 0; 365 | shellPath = /bin/sh; 366 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 367 | showEnvVarsInLog = 0; 368 | }; 369 | /* End PBXShellScriptBuildPhase section */ 370 | 371 | /* Begin PBXSourcesBuildPhase section */ 372 | FCFA52DE1CC8CB0400EB6FC2 /* Sources */ = { 373 | isa = PBXSourcesBuildPhase; 374 | buildActionMask = 2147483647; 375 | files = ( 376 | FCFA531D1CC8CBD600EB6FC2 /* GameScreenRecoder.m in Sources */, 377 | FCFA52ED1CC8CB0400EB6FC2 /* ViewController.m in Sources */, 378 | FCFA52EA1CC8CB0400EB6FC2 /* AppDelegate.m in Sources */, 379 | FCFA52E71CC8CB0400EB6FC2 /* main.m in Sources */, 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | FCFA52F71CC8CB0400EB6FC2 /* Sources */ = { 384 | isa = PBXSourcesBuildPhase; 385 | buildActionMask = 2147483647; 386 | files = ( 387 | FCFA53001CC8CB0400EB6FC2 /* ScreenRecoderForGameTests.m in Sources */, 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | }; 391 | FCFA53021CC8CB0400EB6FC2 /* Sources */ = { 392 | isa = PBXSourcesBuildPhase; 393 | buildActionMask = 2147483647; 394 | files = ( 395 | FCFA530B1CC8CB0400EB6FC2 /* ScreenRecoderForGameUITests.m in Sources */, 396 | ); 397 | runOnlyForDeploymentPostprocessing = 0; 398 | }; 399 | /* End PBXSourcesBuildPhase section */ 400 | 401 | /* Begin PBXTargetDependency section */ 402 | FCFA52FD1CC8CB0400EB6FC2 /* PBXTargetDependency */ = { 403 | isa = PBXTargetDependency; 404 | target = FCFA52E11CC8CB0400EB6FC2 /* ScreenRecoderForGame */; 405 | targetProxy = FCFA52FC1CC8CB0400EB6FC2 /* PBXContainerItemProxy */; 406 | }; 407 | FCFA53081CC8CB0400EB6FC2 /* PBXTargetDependency */ = { 408 | isa = PBXTargetDependency; 409 | target = FCFA52E11CC8CB0400EB6FC2 /* ScreenRecoderForGame */; 410 | targetProxy = FCFA53071CC8CB0400EB6FC2 /* PBXContainerItemProxy */; 411 | }; 412 | /* End PBXTargetDependency section */ 413 | 414 | /* Begin PBXVariantGroup section */ 415 | FCFA52EE1CC8CB0400EB6FC2 /* Main.storyboard */ = { 416 | isa = PBXVariantGroup; 417 | children = ( 418 | FCFA52EF1CC8CB0400EB6FC2 /* Base */, 419 | ); 420 | name = Main.storyboard; 421 | sourceTree = ""; 422 | }; 423 | FCFA52F31CC8CB0400EB6FC2 /* LaunchScreen.storyboard */ = { 424 | isa = PBXVariantGroup; 425 | children = ( 426 | FCFA52F41CC8CB0400EB6FC2 /* Base */, 427 | ); 428 | name = LaunchScreen.storyboard; 429 | sourceTree = ""; 430 | }; 431 | /* End PBXVariantGroup section */ 432 | 433 | /* Begin XCBuildConfiguration section */ 434 | FCFA530D1CC8CB0400EB6FC2 /* Debug */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ALWAYS_SEARCH_USER_PATHS = NO; 438 | CLANG_ANALYZER_NONNULL = YES; 439 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 440 | CLANG_CXX_LIBRARY = "libc++"; 441 | CLANG_ENABLE_MODULES = YES; 442 | CLANG_ENABLE_OBJC_ARC = YES; 443 | CLANG_WARN_BOOL_CONVERSION = YES; 444 | CLANG_WARN_CONSTANT_CONVERSION = YES; 445 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INT_CONVERSION = YES; 449 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 450 | CLANG_WARN_UNREACHABLE_CODE = YES; 451 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 452 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 453 | COPY_PHASE_STRIP = NO; 454 | DEBUG_INFORMATION_FORMAT = dwarf; 455 | ENABLE_STRICT_OBJC_MSGSEND = YES; 456 | ENABLE_TESTABILITY = YES; 457 | GCC_C_LANGUAGE_STANDARD = gnu99; 458 | GCC_DYNAMIC_NO_PIC = NO; 459 | GCC_NO_COMMON_BLOCKS = YES; 460 | GCC_OPTIMIZATION_LEVEL = 0; 461 | GCC_PREPROCESSOR_DEFINITIONS = ( 462 | "DEBUG=1", 463 | "$(inherited)", 464 | ); 465 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 466 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 467 | GCC_WARN_UNDECLARED_SELECTOR = YES; 468 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 469 | GCC_WARN_UNUSED_FUNCTION = YES; 470 | GCC_WARN_UNUSED_VARIABLE = YES; 471 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 472 | MTL_ENABLE_DEBUG_INFO = YES; 473 | ONLY_ACTIVE_ARCH = YES; 474 | SDKROOT = iphoneos; 475 | TARGETED_DEVICE_FAMILY = "1,2"; 476 | }; 477 | name = Debug; 478 | }; 479 | FCFA530E1CC8CB0400EB6FC2 /* Release */ = { 480 | isa = XCBuildConfiguration; 481 | buildSettings = { 482 | ALWAYS_SEARCH_USER_PATHS = NO; 483 | CLANG_ANALYZER_NONNULL = YES; 484 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 485 | CLANG_CXX_LIBRARY = "libc++"; 486 | CLANG_ENABLE_MODULES = YES; 487 | CLANG_ENABLE_OBJC_ARC = YES; 488 | CLANG_WARN_BOOL_CONVERSION = YES; 489 | CLANG_WARN_CONSTANT_CONVERSION = YES; 490 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 491 | CLANG_WARN_EMPTY_BODY = YES; 492 | CLANG_WARN_ENUM_CONVERSION = YES; 493 | CLANG_WARN_INT_CONVERSION = YES; 494 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 495 | CLANG_WARN_UNREACHABLE_CODE = YES; 496 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 497 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 498 | COPY_PHASE_STRIP = NO; 499 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 500 | ENABLE_NS_ASSERTIONS = NO; 501 | ENABLE_STRICT_OBJC_MSGSEND = YES; 502 | GCC_C_LANGUAGE_STANDARD = gnu99; 503 | GCC_NO_COMMON_BLOCKS = YES; 504 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 505 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 506 | GCC_WARN_UNDECLARED_SELECTOR = YES; 507 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 508 | GCC_WARN_UNUSED_FUNCTION = YES; 509 | GCC_WARN_UNUSED_VARIABLE = YES; 510 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 511 | MTL_ENABLE_DEBUG_INFO = NO; 512 | SDKROOT = iphoneos; 513 | TARGETED_DEVICE_FAMILY = "1,2"; 514 | VALIDATE_PRODUCT = YES; 515 | }; 516 | name = Release; 517 | }; 518 | FCFA53101CC8CB0400EB6FC2 /* Debug */ = { 519 | isa = XCBuildConfiguration; 520 | baseConfigurationReference = 72E00202D3F9EE37184F377D /* Pods-ScreenRecoderForGame.debug.xcconfig */; 521 | buildSettings = { 522 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 523 | INFOPLIST_FILE = ScreenRecoderForGame/Info.plist; 524 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 525 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 526 | PRODUCT_BUNDLE_IDENTIFIER = czk.ScreenRecoderForGame; 527 | PRODUCT_NAME = "$(TARGET_NAME)"; 528 | }; 529 | name = Debug; 530 | }; 531 | FCFA53111CC8CB0400EB6FC2 /* Release */ = { 532 | isa = XCBuildConfiguration; 533 | baseConfigurationReference = AE86827476DDF9FAE91B1F7C /* Pods-ScreenRecoderForGame.release.xcconfig */; 534 | buildSettings = { 535 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 536 | INFOPLIST_FILE = ScreenRecoderForGame/Info.plist; 537 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 538 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 539 | PRODUCT_BUNDLE_IDENTIFIER = czk.ScreenRecoderForGame; 540 | PRODUCT_NAME = "$(TARGET_NAME)"; 541 | }; 542 | name = Release; 543 | }; 544 | FCFA53131CC8CB0400EB6FC2 /* Debug */ = { 545 | isa = XCBuildConfiguration; 546 | buildSettings = { 547 | BUNDLE_LOADER = "$(TEST_HOST)"; 548 | INFOPLIST_FILE = ScreenRecoderForGameTests/Info.plist; 549 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 550 | PRODUCT_BUNDLE_IDENTIFIER = czk.ScreenRecoderForGameTests; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ScreenRecoderForGame.app/ScreenRecoderForGame"; 553 | }; 554 | name = Debug; 555 | }; 556 | FCFA53141CC8CB0400EB6FC2 /* Release */ = { 557 | isa = XCBuildConfiguration; 558 | buildSettings = { 559 | BUNDLE_LOADER = "$(TEST_HOST)"; 560 | INFOPLIST_FILE = ScreenRecoderForGameTests/Info.plist; 561 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 562 | PRODUCT_BUNDLE_IDENTIFIER = czk.ScreenRecoderForGameTests; 563 | PRODUCT_NAME = "$(TARGET_NAME)"; 564 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ScreenRecoderForGame.app/ScreenRecoderForGame"; 565 | }; 566 | name = Release; 567 | }; 568 | FCFA53161CC8CB0400EB6FC2 /* Debug */ = { 569 | isa = XCBuildConfiguration; 570 | buildSettings = { 571 | INFOPLIST_FILE = ScreenRecoderForGameUITests/Info.plist; 572 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 573 | PRODUCT_BUNDLE_IDENTIFIER = czk.ScreenRecoderForGameUITests; 574 | PRODUCT_NAME = "$(TARGET_NAME)"; 575 | TEST_TARGET_NAME = ScreenRecoderForGame; 576 | }; 577 | name = Debug; 578 | }; 579 | FCFA53171CC8CB0400EB6FC2 /* Release */ = { 580 | isa = XCBuildConfiguration; 581 | buildSettings = { 582 | INFOPLIST_FILE = ScreenRecoderForGameUITests/Info.plist; 583 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 584 | PRODUCT_BUNDLE_IDENTIFIER = czk.ScreenRecoderForGameUITests; 585 | PRODUCT_NAME = "$(TARGET_NAME)"; 586 | TEST_TARGET_NAME = ScreenRecoderForGame; 587 | }; 588 | name = Release; 589 | }; 590 | /* End XCBuildConfiguration section */ 591 | 592 | /* Begin XCConfigurationList section */ 593 | FCFA52DD1CC8CB0400EB6FC2 /* Build configuration list for PBXProject "ScreenRecoderForGame" */ = { 594 | isa = XCConfigurationList; 595 | buildConfigurations = ( 596 | FCFA530D1CC8CB0400EB6FC2 /* Debug */, 597 | FCFA530E1CC8CB0400EB6FC2 /* Release */, 598 | ); 599 | defaultConfigurationIsVisible = 0; 600 | defaultConfigurationName = Release; 601 | }; 602 | FCFA530F1CC8CB0400EB6FC2 /* Build configuration list for PBXNativeTarget "ScreenRecoderForGame" */ = { 603 | isa = XCConfigurationList; 604 | buildConfigurations = ( 605 | FCFA53101CC8CB0400EB6FC2 /* Debug */, 606 | FCFA53111CC8CB0400EB6FC2 /* Release */, 607 | ); 608 | defaultConfigurationIsVisible = 0; 609 | defaultConfigurationName = Release; 610 | }; 611 | FCFA53121CC8CB0400EB6FC2 /* Build configuration list for PBXNativeTarget "ScreenRecoderForGameTests" */ = { 612 | isa = XCConfigurationList; 613 | buildConfigurations = ( 614 | FCFA53131CC8CB0400EB6FC2 /* Debug */, 615 | FCFA53141CC8CB0400EB6FC2 /* Release */, 616 | ); 617 | defaultConfigurationIsVisible = 0; 618 | defaultConfigurationName = Release; 619 | }; 620 | FCFA53151CC8CB0400EB6FC2 /* Build configuration list for PBXNativeTarget "ScreenRecoderForGameUITests" */ = { 621 | isa = XCConfigurationList; 622 | buildConfigurations = ( 623 | FCFA53161CC8CB0400EB6FC2 /* Debug */, 624 | FCFA53171CC8CB0400EB6FC2 /* Release */, 625 | ); 626 | defaultConfigurationIsVisible = 0; 627 | defaultConfigurationName = Release; 628 | }; 629 | /* End XCConfigurationList section */ 630 | }; 631 | rootObject = FCFA52DA1CC8CB0400EB6FC2 /* Project object */; 632 | } 633 | -------------------------------------------------------------------------------- /ScreenRecoderForGame/Pods/JSPatch/JSPatch/JPEngine.m: -------------------------------------------------------------------------------- 1 | // JPEngine.m 2 | // JSPatch 3 | // 4 | // Created by bang on 15/4/30. 5 | // Copyright (c) 2015 bang. All rights reserved. 6 | // 7 | 8 | #import "JPEngine.h" 9 | #import 10 | #import 11 | 12 | #if TARGET_OS_IPHONE 13 | #import 14 | #endif 15 | 16 | @interface JPBoxing : NSObject 17 | @property (nonatomic) id obj; 18 | @property (nonatomic) void *pointer; 19 | @property (nonatomic) Class cls; 20 | @property (nonatomic, weak) id weakObj; 21 | @property (nonatomic, assign) id assignObj; 22 | - (id)unbox; 23 | - (void *)unboxPointer; 24 | - (Class)unboxClass; 25 | @end 26 | 27 | @implementation JPBoxing 28 | 29 | #define JPBOXING_GEN(_name, _prop, _type) \ 30 | + (instancetype)_name:(_type)obj \ 31 | { \ 32 | JPBoxing *boxing = [[JPBoxing alloc] init]; \ 33 | boxing._prop = obj; \ 34 | return boxing; \ 35 | } 36 | 37 | JPBOXING_GEN(boxObj, obj, id) 38 | JPBOXING_GEN(boxPointer, pointer, void *) 39 | JPBOXING_GEN(boxClass, cls, Class) 40 | JPBOXING_GEN(boxWeakObj, weakObj, id) 41 | JPBOXING_GEN(boxAssignObj, assignObj, id) 42 | 43 | - (id)unbox 44 | { 45 | if (self.obj) return self.obj; 46 | if (self.weakObj) return self.weakObj; 47 | if (self.assignObj) return self.assignObj; 48 | return self; 49 | } 50 | - (void *)unboxPointer 51 | { 52 | return self.pointer; 53 | } 54 | - (Class)unboxClass 55 | { 56 | return self.cls; 57 | } 58 | @end 59 | 60 | static JSContext *_context; 61 | static NSString *_regexStr = @"(? 0 ? methodDict[@"returnType"] : @"void"; 363 | NSString *typeEncode = methodDict[@"typeEncode"]; 364 | 365 | NSArray *argStrArr = [paraString componentsSeparatedByString:@","]; 366 | NSString *selectorName = convertJPSelectorString(jpSelector); 367 | 368 | if ([selectorName componentsSeparatedByString:@":"].count - 1 < argStrArr.count) { 369 | selectorName = [selectorName stringByAppendingString:@":"]; 370 | } 371 | 372 | if (typeEncode) { 373 | addMethodToProtocol(protocol, selectorName, typeEncode, isInstance); 374 | 375 | } else { 376 | if (!_protocolTypeEncodeDict) { 377 | _protocolTypeEncodeDict = [[NSMutableDictionary alloc] init]; 378 | #define JP_DEFINE_TYPE_ENCODE_CASE(_type) \ 379 | [_protocolTypeEncodeDict setObject:[NSString stringWithUTF8String:@encode(_type)] forKey:@#_type];\ 380 | 381 | JP_DEFINE_TYPE_ENCODE_CASE(id); 382 | JP_DEFINE_TYPE_ENCODE_CASE(BOOL); 383 | JP_DEFINE_TYPE_ENCODE_CASE(int); 384 | JP_DEFINE_TYPE_ENCODE_CASE(void); 385 | JP_DEFINE_TYPE_ENCODE_CASE(char); 386 | JP_DEFINE_TYPE_ENCODE_CASE(short); 387 | JP_DEFINE_TYPE_ENCODE_CASE(unsigned short); 388 | JP_DEFINE_TYPE_ENCODE_CASE(unsigned int); 389 | JP_DEFINE_TYPE_ENCODE_CASE(long); 390 | JP_DEFINE_TYPE_ENCODE_CASE(unsigned long); 391 | JP_DEFINE_TYPE_ENCODE_CASE(long long); 392 | JP_DEFINE_TYPE_ENCODE_CASE(float); 393 | JP_DEFINE_TYPE_ENCODE_CASE(double); 394 | JP_DEFINE_TYPE_ENCODE_CASE(CGFloat); 395 | JP_DEFINE_TYPE_ENCODE_CASE(CGSize); 396 | JP_DEFINE_TYPE_ENCODE_CASE(CGRect); 397 | JP_DEFINE_TYPE_ENCODE_CASE(CGPoint); 398 | JP_DEFINE_TYPE_ENCODE_CASE(CGVector); 399 | JP_DEFINE_TYPE_ENCODE_CASE(NSRange); 400 | JP_DEFINE_TYPE_ENCODE_CASE(NSInteger); 401 | JP_DEFINE_TYPE_ENCODE_CASE(Class); 402 | JP_DEFINE_TYPE_ENCODE_CASE(SEL); 403 | JP_DEFINE_TYPE_ENCODE_CASE(void*); 404 | #if TARGET_OS_IPHONE 405 | JP_DEFINE_TYPE_ENCODE_CASE(UIEdgeInsets); 406 | #else 407 | JP_DEFINE_TYPE_ENCODE_CASE(NSEdgeInsets); 408 | #endif 409 | 410 | [_protocolTypeEncodeDict setObject:@"@?" forKey:@"block"]; 411 | [_protocolTypeEncodeDict setObject:@"^@" forKey:@"id*"]; 412 | } 413 | 414 | NSString *returnEncode = _protocolTypeEncodeDict[returnString]; 415 | if (returnEncode.length > 0) { 416 | NSMutableString *encode = [returnEncode mutableCopy]; 417 | [encode appendString:@"@:"]; 418 | for (NSInteger i = 0; i < argStrArr.count; i++) { 419 | NSString *argStr = trim([argStrArr objectAtIndex:i]); 420 | NSString *argEncode = _protocolTypeEncodeDict[argStr]; 421 | if (!argEncode) { 422 | NSString *argClassName = trim([argStr stringByReplacingOccurrencesOfString:@"*" withString:@""]); 423 | if (NSClassFromString(argClassName) != NULL) { 424 | argEncode = @"@"; 425 | } else { 426 | NSCAssert(NO, @"unreconized type %@", argStr); 427 | return; 428 | } 429 | } 430 | [encode appendString:argEncode]; 431 | } 432 | addMethodToProtocol(protocol, selectorName, encode, isInstance); 433 | } 434 | } 435 | } 436 | } 437 | 438 | static void addMethodToProtocol(Protocol* protocol, NSString *selectorName, NSString *typeencoding, BOOL isInstance) 439 | { 440 | SEL sel = NSSelectorFromString(selectorName); 441 | const char* type = [typeencoding UTF8String]; 442 | protocol_addMethodDescription(protocol, sel, type, YES, isInstance); 443 | } 444 | 445 | static NSDictionary *defineClass(NSString *classDeclaration, JSValue *instanceMethods, JSValue *classMethods) 446 | { 447 | NSScanner *scanner = [NSScanner scannerWithString:classDeclaration]; 448 | 449 | NSString *className; 450 | NSString *superClassName; 451 | NSString *protocolNames; 452 | [scanner scanUpToString:@":" intoString:&className]; 453 | if (!scanner.isAtEnd) { 454 | scanner.scanLocation = scanner.scanLocation + 1; 455 | [scanner scanUpToString:@"<" intoString:&superClassName]; 456 | if (!scanner.isAtEnd) { 457 | scanner.scanLocation = scanner.scanLocation + 1; 458 | [scanner scanUpToString:@">" intoString:&protocolNames]; 459 | } 460 | } 461 | 462 | if (!superClassName) superClassName = @"NSObject"; 463 | className = trim(className); 464 | superClassName = trim(superClassName); 465 | 466 | NSArray *protocols = [protocolNames length] ? [protocolNames componentsSeparatedByString:@","] : nil; 467 | 468 | Class cls = NSClassFromString(className); 469 | if (!cls) { 470 | Class superCls = NSClassFromString(superClassName); 471 | if (!superCls) { 472 | NSCAssert(NO, @"can't find the super class %@", superClassName); 473 | return @{@"cls": className}; 474 | } 475 | cls = objc_allocateClassPair(superCls, className.UTF8String, 0); 476 | objc_registerClassPair(cls); 477 | } 478 | 479 | if (protocols.count > 0) { 480 | for (NSString* protocolName in protocols) { 481 | Protocol *protocol = objc_getProtocol([trim(protocolName) cStringUsingEncoding:NSUTF8StringEncoding]); 482 | class_addProtocol (cls, protocol); 483 | } 484 | } 485 | 486 | for (int i = 0; i < 2; i ++) { 487 | BOOL isInstance = i == 0; 488 | JSValue *jsMethods = isInstance ? instanceMethods: classMethods; 489 | 490 | Class currCls = isInstance ? cls: objc_getMetaClass(className.UTF8String); 491 | NSDictionary *methodDict = [jsMethods toDictionary]; 492 | for (NSString *jsMethodName in methodDict.allKeys) { 493 | JSValue *jsMethodArr = [jsMethods valueForProperty:jsMethodName]; 494 | int numberOfArg = [jsMethodArr[0] toInt32]; 495 | NSString *selectorName = convertJPSelectorString(jsMethodName); 496 | 497 | if ([selectorName componentsSeparatedByString:@":"].count - 1 < numberOfArg) { 498 | selectorName = [selectorName stringByAppendingString:@":"]; 499 | } 500 | 501 | JSValue *jsMethod = jsMethodArr[1]; 502 | if (class_respondsToSelector(currCls, NSSelectorFromString(selectorName))) { 503 | overrideMethod(currCls, selectorName, jsMethod, !isInstance, NULL); 504 | } else { 505 | BOOL overrided = NO; 506 | for (NSString *protocolName in protocols) { 507 | char *types = methodTypesInProtocol(protocolName, selectorName, isInstance, YES); 508 | if (!types) types = methodTypesInProtocol(protocolName, selectorName, isInstance, NO); 509 | if (types) { 510 | overrideMethod(currCls, selectorName, jsMethod, !isInstance, types); 511 | free(types); 512 | overrided = YES; 513 | break; 514 | } 515 | } 516 | if (!overrided) { 517 | if (![[jsMethodName substringToIndex:1] isEqualToString:@"_"]) { 518 | NSMutableString *typeDescStr = [@"@@:" mutableCopy]; 519 | for (int i = 0; i < numberOfArg; i ++) { 520 | [typeDescStr appendString:@"@"]; 521 | } 522 | overrideMethod(currCls, selectorName, jsMethod, !isInstance, [typeDescStr cStringUsingEncoding:NSUTF8StringEncoding]); 523 | } 524 | } 525 | } 526 | } 527 | } 528 | 529 | #pragma clang diagnostic push 530 | #pragma clang diagnostic ignored "-Wundeclared-selector" 531 | class_addMethod(cls, @selector(getProp:), (IMP)getPropIMP, "@@:@"); 532 | class_addMethod(cls, @selector(setProp:forKey:), (IMP)setPropIMP, "v@:@@"); 533 | #pragma clang diagnostic pop 534 | 535 | return @{@"cls": className, @"superCls": superClassName}; 536 | } 537 | 538 | static JSValue* getJSFunctionInObjectHierachy(id slf, NSString *selectorName) 539 | { 540 | Class cls = object_getClass(slf); 541 | if (_currInvokeSuperClsName) { 542 | cls = NSClassFromString(_currInvokeSuperClsName); 543 | selectorName = [selectorName stringByReplacingOccurrencesOfString:@"_JPSUPER_" withString:@"_JP"]; 544 | } 545 | JSValue *func = _JSOverideMethods[cls][selectorName]; 546 | while (!func) { 547 | cls = class_getSuperclass(cls); 548 | if (!cls) { 549 | NSCAssert(NO, @"warning can not find selector %@", selectorName); 550 | return nil; 551 | } 552 | func = _JSOverideMethods[cls][selectorName]; 553 | } 554 | return func; 555 | } 556 | 557 | #pragma clang diagnostic pop 558 | 559 | static void JPForwardInvocation(__unsafe_unretained id assignSlf, SEL selector, NSInvocation *invocation) 560 | { 561 | BOOL deallocFlag = NO; 562 | id slf = assignSlf; 563 | NSMethodSignature *methodSignature = [invocation methodSignature]; 564 | NSInteger numberOfArguments = [methodSignature numberOfArguments]; 565 | 566 | NSString *selectorName = NSStringFromSelector(invocation.selector); 567 | NSString *JPSelectorName = [NSString stringWithFormat:@"_JP%@", selectorName]; 568 | SEL JPSelector = NSSelectorFromString(JPSelectorName); 569 | 570 | if (!class_respondsToSelector(object_getClass(slf), JPSelector)) { 571 | JPExcuteORIGForwardInvocation(slf, selector, invocation); 572 | return; 573 | } 574 | 575 | NSMutableArray *argList = [[NSMutableArray alloc] init]; 576 | if ([slf class] == slf) { 577 | [argList addObject:[JSValue valueWithObject:@{@"__clsName": NSStringFromClass([slf class])} inContext:_context]]; 578 | } else if ([selectorName isEqualToString:@"dealloc"]) { 579 | [argList addObject:[JPBoxing boxAssignObj:slf]]; 580 | deallocFlag = YES; 581 | } else { 582 | [argList addObject:[JPBoxing boxWeakObj:slf]]; 583 | } 584 | 585 | for (NSUInteger i = 2; i < numberOfArguments; i++) { 586 | const char *argumentType = [methodSignature getArgumentTypeAtIndex:i]; 587 | switch(argumentType[0] == 'r' ? argumentType[1] : argumentType[0]) { 588 | 589 | #define JP_FWD_ARG_CASE(_typeChar, _type) \ 590 | case _typeChar: { \ 591 | _type arg; \ 592 | [invocation getArgument:&arg atIndex:i]; \ 593 | [argList addObject:@(arg)]; \ 594 | break; \ 595 | } 596 | JP_FWD_ARG_CASE('c', char) 597 | JP_FWD_ARG_CASE('C', unsigned char) 598 | JP_FWD_ARG_CASE('s', short) 599 | JP_FWD_ARG_CASE('S', unsigned short) 600 | JP_FWD_ARG_CASE('i', int) 601 | JP_FWD_ARG_CASE('I', unsigned int) 602 | JP_FWD_ARG_CASE('l', long) 603 | JP_FWD_ARG_CASE('L', unsigned long) 604 | JP_FWD_ARG_CASE('q', long long) 605 | JP_FWD_ARG_CASE('Q', unsigned long long) 606 | JP_FWD_ARG_CASE('f', float) 607 | JP_FWD_ARG_CASE('d', double) 608 | JP_FWD_ARG_CASE('B', BOOL) 609 | case '@': { 610 | __unsafe_unretained id arg; 611 | [invocation getArgument:&arg atIndex:i]; 612 | if ([arg isKindOfClass:NSClassFromString(@"NSBlock")]) { 613 | [argList addObject:(arg ? [arg copy]: _nilObj)]; 614 | } else { 615 | [argList addObject:(arg ? arg: _nilObj)]; 616 | } 617 | break; 618 | } 619 | case '{': { 620 | NSString *typeString = extractStructName([NSString stringWithUTF8String:argumentType]); 621 | #define JP_FWD_ARG_STRUCT(_type, _transFunc) \ 622 | if ([typeString rangeOfString:@#_type].location != NSNotFound) { \ 623 | _type arg; \ 624 | [invocation getArgument:&arg atIndex:i]; \ 625 | [argList addObject:[JSValue _transFunc:arg inContext:_context]]; \ 626 | break; \ 627 | } 628 | JP_FWD_ARG_STRUCT(CGRect, valueWithRect) 629 | JP_FWD_ARG_STRUCT(CGPoint, valueWithPoint) 630 | JP_FWD_ARG_STRUCT(CGSize, valueWithSize) 631 | JP_FWD_ARG_STRUCT(NSRange, valueWithRange) 632 | 633 | @synchronized (_context) { 634 | NSDictionary *structDefine = _registeredStruct[typeString]; 635 | if (structDefine) { 636 | size_t size = sizeOfStructTypes(structDefine[@"types"]); 637 | if (size) { 638 | void *ret = malloc(size); 639 | [invocation getArgument:ret atIndex:i]; 640 | NSDictionary *dict = getDictOfStruct(ret, structDefine); 641 | [argList addObject:[JSValue valueWithObject:dict inContext:_context]]; 642 | free(ret); 643 | break; 644 | } 645 | } 646 | } 647 | 648 | break; 649 | } 650 | case ':': { 651 | SEL selector; 652 | [invocation getArgument:&selector atIndex:i]; 653 | NSString *selectorName = NSStringFromSelector(selector); 654 | [argList addObject:(selectorName ? selectorName: _nilObj)]; 655 | break; 656 | } 657 | case '^': 658 | case '*': { 659 | void *arg; 660 | [invocation getArgument:&arg atIndex:i]; 661 | [argList addObject:[JPBoxing boxPointer:arg]]; 662 | break; 663 | } 664 | case '#': { 665 | Class arg; 666 | [invocation getArgument:&arg atIndex:i]; 667 | [argList addObject:[JPBoxing boxClass:arg]]; 668 | break; 669 | } 670 | default: { 671 | NSLog(@"error type %s", argumentType); 672 | break; 673 | } 674 | } 675 | } 676 | 677 | if (_currInvokeSuperClsName) { 678 | Class cls = NSClassFromString(_currInvokeSuperClsName); 679 | NSString *tmpSelectorName = [[selectorName stringByReplacingOccurrencesOfString:@"_JPSUPER_" withString:@"_JP"] stringByReplacingOccurrencesOfString:@"SUPER_" withString:@"_JP"]; 680 | if (!_JSOverideMethods[cls][tmpSelectorName]) { 681 | NSString *ORIGSelectorName = [selectorName stringByReplacingOccurrencesOfString:@"SUPER_" withString:@"ORIG"]; 682 | [argList removeObjectAtIndex:0]; 683 | id retObj = callSelector(_currInvokeSuperClsName, ORIGSelectorName, [JSValue valueWithObject:argList inContext:_context], [JSValue valueWithObject:@{@"__obj": slf, @"__realClsName": @""} inContext:_context], NO); 684 | id __autoreleasing ret = formatJSToOC([JSValue valueWithObject:retObj inContext:_context]); 685 | [invocation setReturnValue:&ret]; 686 | return; 687 | } 688 | } 689 | 690 | NSArray *params = _formatOCToJSList(argList); 691 | const char *returnType = [methodSignature methodReturnType]; 692 | 693 | switch (returnType[0] == 'r' ? returnType[1] : returnType[0]) { 694 | #define JP_FWD_RET_CALL_JS \ 695 | JSValue *fun = getJSFunctionInObjectHierachy(slf, JPSelectorName); \ 696 | JSValue *jsval; \ 697 | [_JSMethodForwardCallLock lock]; \ 698 | jsval = [fun callWithArguments:params]; \ 699 | [_JSMethodForwardCallLock unlock]; \ 700 | while (![jsval isNull] && ![jsval isUndefined] && [jsval hasProperty:@"__isPerformInOC"]) { \ 701 | NSArray *args = nil; \ 702 | JSValue *cb = jsval[@"cb"]; \ 703 | if ([jsval hasProperty:@"sel"]) { \ 704 | id callRet = callSelector(![jsval[@"clsName"] isUndefined] ? [jsval[@"clsName"] toString] : nil, [jsval[@"sel"] toString], jsval[@"args"], ![jsval[@"obj"] isUndefined] ? jsval[@"obj"] : nil, NO); \ 705 | args = @[[_context[@"_formatOCToJS"] callWithArguments:callRet ? @[callRet] : _formatOCToJSList(@[_nilObj])]]; \ 706 | } \ 707 | [_JSMethodForwardCallLock lock]; \ 708 | jsval = [cb callWithArguments:args]; \ 709 | [_JSMethodForwardCallLock unlock]; \ 710 | } 711 | 712 | #define JP_FWD_RET_CASE_RET(_typeChar, _type, _retCode) \ 713 | case _typeChar : { \ 714 | JP_FWD_RET_CALL_JS \ 715 | _retCode \ 716 | [invocation setReturnValue:&ret];\ 717 | break; \ 718 | } 719 | 720 | #define JP_FWD_RET_CASE(_typeChar, _type, _typeSelector) \ 721 | JP_FWD_RET_CASE_RET(_typeChar, _type, _type ret = [[jsval toObject] _typeSelector];) \ 722 | 723 | #define JP_FWD_RET_CODE_ID \ 724 | id __autoreleasing ret = formatJSToOC(jsval); \ 725 | if (ret == _nilObj || \ 726 | ([ret isKindOfClass:[NSNumber class]] && strcmp([ret objCType], "c") == 0 && ![ret boolValue])) ret = nil; \ 727 | 728 | #define JP_FWD_RET_CODE_POINTER \ 729 | void *ret; \ 730 | id obj = formatJSToOC(jsval); \ 731 | if ([obj isKindOfClass:[JPBoxing class]]) { \ 732 | ret = [((JPBoxing *)obj) unboxPointer]; \ 733 | } 734 | 735 | #define JP_FWD_RET_CODE_CLASS \ 736 | Class ret; \ 737 | id obj = formatJSToOC(jsval); \ 738 | if ([obj isKindOfClass:[JPBoxing class]]) { \ 739 | ret = [((JPBoxing *)obj) unboxClass]; \ 740 | } 741 | 742 | #define JP_FWD_RET_CODE_SEL \ 743 | SEL ret; \ 744 | id obj = formatJSToOC(jsval); \ 745 | if ([obj isKindOfClass:[NSString class]]) { \ 746 | ret = NSSelectorFromString(obj); \ 747 | } 748 | 749 | JP_FWD_RET_CASE_RET('@', id, JP_FWD_RET_CODE_ID) 750 | JP_FWD_RET_CASE_RET('^', void*, JP_FWD_RET_CODE_POINTER) 751 | JP_FWD_RET_CASE_RET('*', void*, JP_FWD_RET_CODE_POINTER) 752 | JP_FWD_RET_CASE_RET('#', Class, JP_FWD_RET_CODE_CLASS) 753 | JP_FWD_RET_CASE_RET(':', SEL, JP_FWD_RET_CODE_SEL) 754 | 755 | JP_FWD_RET_CASE('c', char, charValue) 756 | JP_FWD_RET_CASE('C', unsigned char, unsignedCharValue) 757 | JP_FWD_RET_CASE('s', short, shortValue) 758 | JP_FWD_RET_CASE('S', unsigned short, unsignedShortValue) 759 | JP_FWD_RET_CASE('i', int, intValue) 760 | JP_FWD_RET_CASE('I', unsigned int, unsignedIntValue) 761 | JP_FWD_RET_CASE('l', long, longValue) 762 | JP_FWD_RET_CASE('L', unsigned long, unsignedLongValue) 763 | JP_FWD_RET_CASE('q', long long, longLongValue) 764 | JP_FWD_RET_CASE('Q', unsigned long long, unsignedLongLongValue) 765 | JP_FWD_RET_CASE('f', float, floatValue) 766 | JP_FWD_RET_CASE('d', double, doubleValue) 767 | JP_FWD_RET_CASE('B', BOOL, boolValue) 768 | 769 | case 'v': { 770 | JP_FWD_RET_CALL_JS 771 | break; 772 | } 773 | 774 | case '{': { 775 | NSString *typeString = extractStructName([NSString stringWithUTF8String:returnType]); 776 | #define JP_FWD_RET_STRUCT(_type, _funcSuffix) \ 777 | if ([typeString rangeOfString:@#_type].location != NSNotFound) { \ 778 | JP_FWD_RET_CALL_JS \ 779 | _type ret = [jsval _funcSuffix]; \ 780 | [invocation setReturnValue:&ret];\ 781 | break; \ 782 | } 783 | JP_FWD_RET_STRUCT(CGRect, toRect) 784 | JP_FWD_RET_STRUCT(CGPoint, toPoint) 785 | JP_FWD_RET_STRUCT(CGSize, toSize) 786 | JP_FWD_RET_STRUCT(NSRange, toRange) 787 | 788 | @synchronized (_context) { 789 | NSDictionary *structDefine = _registeredStruct[typeString]; 790 | if (structDefine) { 791 | size_t size = sizeOfStructTypes(structDefine[@"types"]); 792 | JP_FWD_RET_CALL_JS 793 | void *ret = malloc(size); 794 | NSDictionary *dict = formatJSToOC(jsval); 795 | getStructDataWithDict(ret, dict, structDefine); 796 | [invocation setReturnValue:ret]; 797 | free(ret); 798 | } 799 | } 800 | break; 801 | } 802 | default: { 803 | break; 804 | } 805 | } 806 | 807 | if (deallocFlag) { 808 | slf = nil; 809 | Class instClass = object_getClass(assignSlf); 810 | Method deallocMethod = class_getInstanceMethod(instClass, NSSelectorFromString(@"ORIGdealloc")); 811 | void (*originalDealloc)(__unsafe_unretained id, SEL) = (__typeof__(originalDealloc))method_getImplementation(deallocMethod); 812 | originalDealloc(assignSlf, NSSelectorFromString(@"dealloc")); 813 | } 814 | } 815 | 816 | static void JPExcuteORIGForwardInvocation(id slf, SEL selector, NSInvocation *invocation) 817 | { 818 | #pragma clang diagnostic push 819 | #pragma clang diagnostic ignored "-Wundeclared-selector" 820 | SEL origForwardSelector = @selector(ORIGforwardInvocation:); 821 | #pragma clang diagnostic pop 822 | 823 | if ([slf respondsToSelector:origForwardSelector]) { 824 | 825 | NSMethodSignature *methodSignature = [slf methodSignatureForSelector:origForwardSelector]; 826 | if (!methodSignature) { 827 | NSCAssert(methodSignature, @"unrecognized selector -ORIGforwardInvocation: for instance %@", slf); 828 | return; 829 | } 830 | NSInvocation *forwardInv= [NSInvocation invocationWithMethodSignature:methodSignature]; 831 | [forwardInv setTarget:slf]; 832 | [forwardInv setSelector:origForwardSelector]; 833 | [forwardInv setArgument:&invocation atIndex:2]; 834 | [forwardInv invoke]; 835 | 836 | } else { 837 | NSString *superForwardName = @"JPSUPER_ForwardInvocation"; 838 | SEL superForwardSelector = NSSelectorFromString(superForwardName); 839 | 840 | if (![slf respondsToSelector:superForwardSelector]) { 841 | Class superCls = [[slf class] superclass]; 842 | Method superForwardMethod = class_getInstanceMethod(superCls, @selector(forwardInvocation:)); 843 | IMP superForwardIMP = method_getImplementation(superForwardMethod); 844 | class_addMethod([slf class], superForwardSelector, superForwardIMP, method_getTypeEncoding(superForwardMethod)); 845 | } 846 | 847 | NSMethodSignature *methodSignature = [slf methodSignatureForSelector:@selector(forwardInvocation:)]; 848 | NSInvocation *forwardInv= [NSInvocation invocationWithMethodSignature:methodSignature]; 849 | [forwardInv setTarget:slf]; 850 | [forwardInv setSelector:superForwardSelector]; 851 | [forwardInv setArgument:&invocation atIndex:2]; 852 | [forwardInv invoke]; 853 | } 854 | } 855 | 856 | static void _initJPOverideMethods(Class cls) { 857 | if (!_JSOverideMethods) { 858 | _JSOverideMethods = [[NSMutableDictionary alloc] init]; 859 | } 860 | if (!_JSOverideMethods[cls]) { 861 | _JSOverideMethods[(id)cls] = [[NSMutableDictionary alloc] init]; 862 | } 863 | } 864 | 865 | static void overrideMethod(Class cls, NSString *selectorName, JSValue *function, BOOL isClassMethod, const char *typeDescription) 866 | { 867 | SEL selector = NSSelectorFromString(selectorName); 868 | 869 | if (!typeDescription) { 870 | Method method = class_getInstanceMethod(cls, selector); 871 | typeDescription = (char *)method_getTypeEncoding(method); 872 | } 873 | 874 | IMP originalImp = class_respondsToSelector(cls, selector) ? class_getMethodImplementation(cls, selector) : NULL; 875 | 876 | IMP msgForwardIMP = _objc_msgForward; 877 | #if !defined(__arm64__) 878 | if (typeDescription[0] == '{') { 879 | //In some cases that returns struct, we should use the '_stret' API: 880 | //http://sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html 881 | //NSMethodSignature knows the detail but has no API to return, we can only get the info from debugDescription. 882 | NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:typeDescription]; 883 | if ([methodSignature.debugDescription rangeOfString:@"is special struct return? YES"].location != NSNotFound) { 884 | msgForwardIMP = (IMP)_objc_msgForward_stret; 885 | } 886 | } 887 | #endif 888 | 889 | class_replaceMethod(cls, selector, msgForwardIMP, typeDescription); 890 | 891 | #pragma clang diagnostic push 892 | #pragma clang diagnostic ignored "-Wundeclared-selector" 893 | if (class_getMethodImplementation(cls, @selector(forwardInvocation:)) != (IMP)JPForwardInvocation) { 894 | IMP originalForwardImp = class_replaceMethod(cls, @selector(forwardInvocation:), (IMP)JPForwardInvocation, "v@:@"); 895 | class_addMethod(cls, @selector(ORIGforwardInvocation:), originalForwardImp, "v@:@"); 896 | } 897 | #pragma clang diagnostic pop 898 | 899 | if (class_respondsToSelector(cls, selector)) { 900 | NSString *originalSelectorName = [NSString stringWithFormat:@"ORIG%@", selectorName]; 901 | SEL originalSelector = NSSelectorFromString(originalSelectorName); 902 | if(!class_respondsToSelector(cls, originalSelector)) { 903 | class_addMethod(cls, originalSelector, originalImp, typeDescription); 904 | } 905 | } 906 | 907 | NSString *JPSelectorName = [NSString stringWithFormat:@"_JP%@", selectorName]; 908 | SEL JPSelector = NSSelectorFromString(JPSelectorName); 909 | 910 | _initJPOverideMethods(cls); 911 | _JSOverideMethods[cls][JPSelectorName] = function; 912 | 913 | class_addMethod(cls, JPSelector, msgForwardIMP, typeDescription); 914 | } 915 | 916 | #pragma mark - 917 | 918 | static id callSelector(NSString *className, NSString *selectorName, JSValue *arguments, JSValue *instance, BOOL isSuper) 919 | { 920 | NSString *realClsName = [[instance valueForProperty:@"__realClsName"] toString]; 921 | 922 | if (instance) { 923 | instance = formatJSToOC(instance); 924 | if (!instance || instance == _nilObj || [instance isKindOfClass:[JPBoxing class]]) return @{@"__isNil": @(YES)}; 925 | } 926 | id argumentsObj = formatJSToOC(arguments); 927 | 928 | if (instance && [selectorName isEqualToString:@"toJS"]) { 929 | if ([instance isKindOfClass:[NSString class]] || [instance isKindOfClass:[NSDictionary class]] || [instance isKindOfClass:[NSArray class]] || [instance isKindOfClass:[NSDate class]]) { 930 | return _unboxOCObjectToJS(instance); 931 | } 932 | } 933 | 934 | Class cls = instance ? [instance class] : NSClassFromString(className); 935 | SEL selector = NSSelectorFromString(selectorName); 936 | 937 | NSString *superClassName = nil; 938 | if (isSuper) { 939 | NSString *superSelectorName = [NSString stringWithFormat:@"SUPER_%@", selectorName]; 940 | SEL superSelector = NSSelectorFromString(superSelectorName); 941 | 942 | Class superCls; 943 | if (realClsName.length) { 944 | Class defineClass = NSClassFromString(realClsName); 945 | superCls = defineClass ? [defineClass superclass] : [cls superclass]; 946 | } else { 947 | superCls = [cls superclass]; 948 | } 949 | 950 | Method superMethod = class_getInstanceMethod(superCls, selector); 951 | IMP superIMP = method_getImplementation(superMethod); 952 | 953 | class_addMethod(cls, superSelector, superIMP, method_getTypeEncoding(superMethod)); 954 | 955 | NSString *JPSelectorName = [NSString stringWithFormat:@"_JP%@", selectorName]; 956 | JSValue *overideFunction = _JSOverideMethods[superCls][JPSelectorName]; 957 | if (overideFunction) { 958 | overrideMethod(cls, superSelectorName, overideFunction, NO, NULL); 959 | } 960 | 961 | selector = superSelector; 962 | superClassName = NSStringFromClass(superCls); 963 | } 964 | 965 | 966 | NSMutableArray *_markArray; 967 | 968 | NSInvocation *invocation; 969 | NSMethodSignature *methodSignature; 970 | if (!_JSMethodSignatureCache) { 971 | _JSMethodSignatureCache = [[NSMutableDictionary alloc]init]; 972 | } 973 | if (instance) { 974 | [_JSMethodSignatureLock lock]; 975 | if (!_JSMethodSignatureCache[cls]) { 976 | _JSMethodSignatureCache[(id)cls] = [[NSMutableDictionary alloc]init]; 977 | } 978 | methodSignature = _JSMethodSignatureCache[cls][selectorName]; 979 | if (!methodSignature) { 980 | methodSignature = [cls instanceMethodSignatureForSelector:selector]; 981 | _JSMethodSignatureCache[cls][selectorName] = methodSignature; 982 | } 983 | [_JSMethodSignatureLock unlock]; 984 | if (!methodSignature) { 985 | NSCAssert(methodSignature, @"unrecognized selector %@ for instance %@", selectorName, instance); 986 | return nil; 987 | } 988 | invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; 989 | [invocation setTarget:instance]; 990 | } else { 991 | methodSignature = [cls methodSignatureForSelector:selector]; 992 | if (!methodSignature) { 993 | NSCAssert(methodSignature, @"unrecognized selector %@ for class %@", selectorName, className); 994 | return nil; 995 | } 996 | invocation= [NSInvocation invocationWithMethodSignature:methodSignature]; 997 | [invocation setTarget:cls]; 998 | } 999 | [invocation setSelector:selector]; 1000 | 1001 | NSUInteger numberOfArguments = methodSignature.numberOfArguments; 1002 | NSInteger inputArguments = [(NSArray *)argumentsObj count]; 1003 | if (inputArguments > numberOfArguments - 2) { 1004 | // calling variable argument method, only support parameter type `id` and return type `id` 1005 | id sender = instance != nil ? instance : cls; 1006 | id result = invokeVariableParameterMethod(argumentsObj, methodSignature, sender, selector); 1007 | return formatOCToJS(result); 1008 | } 1009 | 1010 | for (NSUInteger i = 2; i < numberOfArguments; i++) { 1011 | const char *argumentType = [methodSignature getArgumentTypeAtIndex:i]; 1012 | id valObj = argumentsObj[i-2]; 1013 | switch (argumentType[0] == 'r' ? argumentType[1] : argumentType[0]) { 1014 | 1015 | #define JP_CALL_ARG_CASE(_typeString, _type, _selector) \ 1016 | case _typeString: { \ 1017 | _type value = [valObj _selector]; \ 1018 | [invocation setArgument:&value atIndex:i];\ 1019 | break; \ 1020 | } 1021 | 1022 | JP_CALL_ARG_CASE('c', char, charValue) 1023 | JP_CALL_ARG_CASE('C', unsigned char, unsignedCharValue) 1024 | JP_CALL_ARG_CASE('s', short, shortValue) 1025 | JP_CALL_ARG_CASE('S', unsigned short, unsignedShortValue) 1026 | JP_CALL_ARG_CASE('i', int, intValue) 1027 | JP_CALL_ARG_CASE('I', unsigned int, unsignedIntValue) 1028 | JP_CALL_ARG_CASE('l', long, longValue) 1029 | JP_CALL_ARG_CASE('L', unsigned long, unsignedLongValue) 1030 | JP_CALL_ARG_CASE('q', long long, longLongValue) 1031 | JP_CALL_ARG_CASE('Q', unsigned long long, unsignedLongLongValue) 1032 | JP_CALL_ARG_CASE('f', float, floatValue) 1033 | JP_CALL_ARG_CASE('d', double, doubleValue) 1034 | JP_CALL_ARG_CASE('B', BOOL, boolValue) 1035 | 1036 | case ':': { 1037 | SEL value = nil; 1038 | if (valObj != _nilObj) { 1039 | value = NSSelectorFromString(valObj); 1040 | } 1041 | [invocation setArgument:&value atIndex:i]; 1042 | break; 1043 | } 1044 | case '{': { 1045 | NSString *typeString = extractStructName([NSString stringWithUTF8String:argumentType]); 1046 | JSValue *val = arguments[i-2]; 1047 | #define JP_CALL_ARG_STRUCT(_type, _methodName) \ 1048 | if ([typeString rangeOfString:@#_type].location != NSNotFound) { \ 1049 | _type value = [val _methodName]; \ 1050 | [invocation setArgument:&value atIndex:i]; \ 1051 | break; \ 1052 | } 1053 | JP_CALL_ARG_STRUCT(CGRect, toRect) 1054 | JP_CALL_ARG_STRUCT(CGPoint, toPoint) 1055 | JP_CALL_ARG_STRUCT(CGSize, toSize) 1056 | JP_CALL_ARG_STRUCT(NSRange, toRange) 1057 | @synchronized (_context) { 1058 | NSDictionary *structDefine = _registeredStruct[typeString]; 1059 | if (structDefine) { 1060 | size_t size = sizeOfStructTypes(structDefine[@"types"]); 1061 | void *ret = malloc(size); 1062 | getStructDataWithDict(ret, valObj, structDefine); 1063 | [invocation setArgument:ret atIndex:i]; 1064 | free(ret); 1065 | break; 1066 | } 1067 | } 1068 | 1069 | break; 1070 | } 1071 | case '*': 1072 | case '^': { 1073 | if ([valObj isKindOfClass:[JPBoxing class]]) { 1074 | void *value = [((JPBoxing *)valObj) unboxPointer]; 1075 | 1076 | if (argumentType[1] == '@') { 1077 | if (!_TMPMemoryPool) { 1078 | _TMPMemoryPool = [[NSMutableDictionary alloc] init]; 1079 | } 1080 | if (!_markArray) { 1081 | _markArray = [[NSMutableArray alloc] init]; 1082 | } 1083 | memset(value, 0, sizeof(id)); 1084 | [_markArray addObject:valObj]; 1085 | } 1086 | 1087 | [invocation setArgument:&value atIndex:i]; 1088 | break; 1089 | } 1090 | } 1091 | case '#': { 1092 | if ([valObj isKindOfClass:[JPBoxing class]]) { 1093 | Class value = [((JPBoxing *)valObj) unboxClass]; 1094 | [invocation setArgument:&value atIndex:i]; 1095 | break; 1096 | } 1097 | } 1098 | default: { 1099 | if (valObj == _nullObj) { 1100 | valObj = [NSNull null]; 1101 | [invocation setArgument:&valObj atIndex:i]; 1102 | break; 1103 | } 1104 | if (valObj == _nilObj || 1105 | ([valObj isKindOfClass:[NSNumber class]] && strcmp([valObj objCType], "c") == 0 && ![valObj boolValue])) { 1106 | valObj = nil; 1107 | [invocation setArgument:&valObj atIndex:i]; 1108 | break; 1109 | } 1110 | if ([(JSValue *)arguments[i-2] hasProperty:@"__isBlock"]) { 1111 | __autoreleasing id cb = genCallbackBlock(arguments[i-2]); 1112 | [invocation setArgument:&cb atIndex:i]; 1113 | } else { 1114 | [invocation setArgument:&valObj atIndex:i]; 1115 | } 1116 | } 1117 | } 1118 | } 1119 | 1120 | if (superClassName) _currInvokeSuperClsName = superClassName; 1121 | [invocation invoke]; 1122 | if (superClassName) _currInvokeSuperClsName = nil; 1123 | if ([_markArray count] > 0) { 1124 | for (JPBoxing *box in _markArray) { 1125 | void *pointer = [box unboxPointer]; 1126 | id obj = *((__unsafe_unretained id *)pointer); 1127 | if (obj) { 1128 | @synchronized(_TMPMemoryPool) { 1129 | [_TMPMemoryPool setObject:obj forKey:[NSNumber numberWithInteger:[(NSObject*)obj hash]]]; 1130 | } 1131 | } 1132 | } 1133 | } 1134 | const char *returnType = [methodSignature methodReturnType]; 1135 | id returnValue; 1136 | if (strncmp(returnType, "v", 1) != 0) { 1137 | if (strncmp(returnType, "@", 1) == 0) { 1138 | void *result; 1139 | [invocation getReturnValue:&result]; 1140 | 1141 | //For performance, ignore the other methods prefix with alloc/new/copy/mutableCopy 1142 | if ([selectorName isEqualToString:@"alloc"] || [selectorName isEqualToString:@"new"] || 1143 | [selectorName isEqualToString:@"copy"] || [selectorName isEqualToString:@"mutableCopy"]) { 1144 | returnValue = (__bridge_transfer id)result; 1145 | } else { 1146 | returnValue = (__bridge id)result; 1147 | } 1148 | return formatOCToJS(returnValue); 1149 | 1150 | } else { 1151 | switch (returnType[0] == 'r' ? returnType[1] : returnType[0]) { 1152 | 1153 | #define JP_CALL_RET_CASE(_typeString, _type) \ 1154 | case _typeString: { \ 1155 | _type tempResultSet; \ 1156 | [invocation getReturnValue:&tempResultSet];\ 1157 | returnValue = @(tempResultSet); \ 1158 | break; \ 1159 | } 1160 | 1161 | JP_CALL_RET_CASE('c', char) 1162 | JP_CALL_RET_CASE('C', unsigned char) 1163 | JP_CALL_RET_CASE('s', short) 1164 | JP_CALL_RET_CASE('S', unsigned short) 1165 | JP_CALL_RET_CASE('i', int) 1166 | JP_CALL_RET_CASE('I', unsigned int) 1167 | JP_CALL_RET_CASE('l', long) 1168 | JP_CALL_RET_CASE('L', unsigned long) 1169 | JP_CALL_RET_CASE('q', long long) 1170 | JP_CALL_RET_CASE('Q', unsigned long long) 1171 | JP_CALL_RET_CASE('f', float) 1172 | JP_CALL_RET_CASE('d', double) 1173 | JP_CALL_RET_CASE('B', BOOL) 1174 | 1175 | case '{': { 1176 | NSString *typeString = extractStructName([NSString stringWithUTF8String:returnType]); 1177 | #define JP_CALL_RET_STRUCT(_type, _methodName) \ 1178 | if ([typeString rangeOfString:@#_type].location != NSNotFound) { \ 1179 | _type result; \ 1180 | [invocation getReturnValue:&result]; \ 1181 | return [JSValue _methodName:result inContext:_context]; \ 1182 | } 1183 | JP_CALL_RET_STRUCT(CGRect, valueWithRect) 1184 | JP_CALL_RET_STRUCT(CGPoint, valueWithPoint) 1185 | JP_CALL_RET_STRUCT(CGSize, valueWithSize) 1186 | JP_CALL_RET_STRUCT(NSRange, valueWithRange) 1187 | @synchronized (_context) { 1188 | NSDictionary *structDefine = _registeredStruct[typeString]; 1189 | if (structDefine) { 1190 | size_t size = sizeOfStructTypes(structDefine[@"types"]); 1191 | void *ret = malloc(size); 1192 | [invocation getReturnValue:ret]; 1193 | NSDictionary *dict = getDictOfStruct(ret, structDefine); 1194 | free(ret); 1195 | return dict; 1196 | } 1197 | } 1198 | break; 1199 | } 1200 | case '*': 1201 | case '^': { 1202 | void *result; 1203 | [invocation getReturnValue:&result]; 1204 | returnValue = formatOCToJS([JPBoxing boxPointer:result]); 1205 | break; 1206 | } 1207 | case '#': { 1208 | Class result; 1209 | [invocation getReturnValue:&result]; 1210 | returnValue = formatOCToJS([JPBoxing boxClass:result]); 1211 | break; 1212 | } 1213 | } 1214 | return returnValue; 1215 | } 1216 | } 1217 | return nil; 1218 | } 1219 | 1220 | id (*new_msgSend1)(id, SEL, id,...) = (id (*)(id, SEL, id,...)) objc_msgSend; 1221 | id (*new_msgSend2)(id, SEL, id, id,...) = (id (*)(id, SEL, id, id,...)) objc_msgSend; 1222 | id (*new_msgSend3)(id, SEL, id, id, id,...) = (id (*)(id, SEL, id, id, id,...)) objc_msgSend; 1223 | id (*new_msgSend4)(id, SEL, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id,...)) objc_msgSend; 1224 | id (*new_msgSend5)(id, SEL, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id,...)) objc_msgSend; 1225 | id (*new_msgSend6)(id, SEL, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id,...)) objc_msgSend; 1226 | id (*new_msgSend7)(id, SEL, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id,id,...)) objc_msgSend; 1227 | id (*new_msgSend8)(id, SEL, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id,...)) objc_msgSend; 1228 | id (*new_msgSend9)(id, SEL, id, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id, id, ...)) objc_msgSend; 1229 | id (*new_msgSend10)(id, SEL, id, id, id, id, id, id, id, id, id, id,...) = (id (*)(id, SEL, id, id, id, id, id, id, id, id, id, id,...)) objc_msgSend; 1230 | 1231 | static id invokeVariableParameterMethod(NSMutableArray *origArgumentsList, NSMethodSignature *methodSignature, id sender, SEL selector) { 1232 | 1233 | NSInteger inputArguments = [(NSArray *)origArgumentsList count]; 1234 | NSUInteger numberOfArguments = methodSignature.numberOfArguments; 1235 | 1236 | NSMutableArray *argumentsList = [[NSMutableArray alloc] init]; 1237 | for (NSUInteger j = 0; j < inputArguments; j++) { 1238 | NSInteger index = MIN(j + 2, numberOfArguments - 1); 1239 | const char *argumentType = [methodSignature getArgumentTypeAtIndex:index]; 1240 | id valObj = origArgumentsList[j]; 1241 | char argumentTypeChar = argumentType[0] == 'r' ? argumentType[1] : argumentType[0]; 1242 | if (argumentTypeChar == '@') { 1243 | [argumentsList addObject:valObj]; 1244 | } else { 1245 | return nil; 1246 | } 1247 | } 1248 | 1249 | id results = nil; 1250 | numberOfArguments = numberOfArguments - 2; 1251 | 1252 | //If you want to debug the macro code below, replace it to the expanded code: 1253 | //https://gist.github.com/bang590/ca3720ae1da594252a2e 1254 | #define JP_G_ARG(_idx) getArgument(argumentsList[_idx]) 1255 | #define JP_CALL_MSGSEND_ARG1(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0)); 1256 | #define JP_CALL_MSGSEND_ARG2(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1)); 1257 | #define JP_CALL_MSGSEND_ARG3(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2)); 1258 | #define JP_CALL_MSGSEND_ARG4(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3)); 1259 | #define JP_CALL_MSGSEND_ARG5(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4)); 1260 | #define JP_CALL_MSGSEND_ARG6(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5)); 1261 | #define JP_CALL_MSGSEND_ARG7(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6)); 1262 | #define JP_CALL_MSGSEND_ARG8(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7)); 1263 | #define JP_CALL_MSGSEND_ARG9(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7), JP_G_ARG(8)); 1264 | #define JP_CALL_MSGSEND_ARG10(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7), JP_G_ARG(8), JP_G_ARG(9)); 1265 | #define JP_CALL_MSGSEND_ARG11(_num) results = new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7), JP_G_ARG(8), JP_G_ARG(9), JP_G_ARG(10)); 1266 | 1267 | #define JP_IF_REAL_ARG_COUNT(_num) if([argumentsList count] == _num) 1268 | 1269 | #define JP_DEAL_MSGSEND(_realArgCount, _defineArgCount) \ 1270 | if(numberOfArguments == _defineArgCount) { \ 1271 | JP_CALL_MSGSEND_ARG##_realArgCount(_defineArgCount) \ 1272 | } 1273 | 1274 | JP_IF_REAL_ARG_COUNT(1) { JP_CALL_MSGSEND_ARG1(1) } 1275 | JP_IF_REAL_ARG_COUNT(2) { JP_DEAL_MSGSEND(2, 1) JP_DEAL_MSGSEND(2, 2) } 1276 | JP_IF_REAL_ARG_COUNT(3) { JP_DEAL_MSGSEND(3, 1) JP_DEAL_MSGSEND(3, 2) JP_DEAL_MSGSEND(3, 3) } 1277 | JP_IF_REAL_ARG_COUNT(4) { JP_DEAL_MSGSEND(4, 1) JP_DEAL_MSGSEND(4, 2) JP_DEAL_MSGSEND(4, 3) JP_DEAL_MSGSEND(4, 4) } 1278 | JP_IF_REAL_ARG_COUNT(5) { JP_DEAL_MSGSEND(5, 1) JP_DEAL_MSGSEND(5, 2) JP_DEAL_MSGSEND(5, 3) JP_DEAL_MSGSEND(5, 4) JP_DEAL_MSGSEND(5, 5) } 1279 | JP_IF_REAL_ARG_COUNT(6) { JP_DEAL_MSGSEND(6, 1) JP_DEAL_MSGSEND(6, 2) JP_DEAL_MSGSEND(6, 3) JP_DEAL_MSGSEND(6, 4) JP_DEAL_MSGSEND(6, 5) JP_DEAL_MSGSEND(6, 6) } 1280 | JP_IF_REAL_ARG_COUNT(7) { JP_DEAL_MSGSEND(7, 1) JP_DEAL_MSGSEND(7, 2) JP_DEAL_MSGSEND(7, 3) JP_DEAL_MSGSEND(7, 4) JP_DEAL_MSGSEND(7, 5) JP_DEAL_MSGSEND(7, 6) JP_DEAL_MSGSEND(7, 7) } 1281 | JP_IF_REAL_ARG_COUNT(8) { JP_DEAL_MSGSEND(8, 1) JP_DEAL_MSGSEND(8, 2) JP_DEAL_MSGSEND(8, 3) JP_DEAL_MSGSEND(8, 4) JP_DEAL_MSGSEND(8, 5) JP_DEAL_MSGSEND(8, 6) JP_DEAL_MSGSEND(8, 7) JP_DEAL_MSGSEND(8, 8) } 1282 | JP_IF_REAL_ARG_COUNT(9) { JP_DEAL_MSGSEND(9, 1) JP_DEAL_MSGSEND(9, 2) JP_DEAL_MSGSEND(9, 3) JP_DEAL_MSGSEND(9, 4) JP_DEAL_MSGSEND(9, 5) JP_DEAL_MSGSEND(9, 6) JP_DEAL_MSGSEND(9, 7) JP_DEAL_MSGSEND(9, 8) JP_DEAL_MSGSEND(9, 9) } 1283 | JP_IF_REAL_ARG_COUNT(10) { JP_DEAL_MSGSEND(10, 1) JP_DEAL_MSGSEND(10, 2) JP_DEAL_MSGSEND(10, 3) JP_DEAL_MSGSEND(10, 4) JP_DEAL_MSGSEND(10, 5) JP_DEAL_MSGSEND(10, 6) JP_DEAL_MSGSEND(10, 7) JP_DEAL_MSGSEND(10, 8) JP_DEAL_MSGSEND(10, 9) JP_DEAL_MSGSEND(10, 10) } 1284 | 1285 | return results; 1286 | } 1287 | 1288 | static id getArgument(id valObj){ 1289 | if (valObj == _nilObj || 1290 | ([valObj isKindOfClass:[NSNumber class]] && strcmp([valObj objCType], "c") == 0 && ![valObj boolValue])) { 1291 | return nil; 1292 | } 1293 | return valObj; 1294 | } 1295 | 1296 | #pragma mark - 1297 | 1298 | static id genCallbackBlock(JSValue *jsVal) 1299 | { 1300 | #define BLK_TRAITS_ARG(_idx, _paramName) \ 1301 | if (_idx < argTypes.count) { \ 1302 | if (blockTypeIsObject(trim(argTypes[_idx]))) { \ 1303 | [list addObject:formatOCToJS((__bridge id)_paramName)]; \ 1304 | } else { \ 1305 | [list addObject:formatOCToJS([NSNumber numberWithLongLong:(long long)_paramName])]; \ 1306 | } \ 1307 | } 1308 | 1309 | NSArray *argTypes = [[jsVal[@"args"] toString] componentsSeparatedByString:@","]; 1310 | id cb = ^id(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5) { 1311 | NSMutableArray *list = [[NSMutableArray alloc] init]; 1312 | BLK_TRAITS_ARG(0, p0) 1313 | BLK_TRAITS_ARG(1, p1) 1314 | BLK_TRAITS_ARG(2, p2) 1315 | BLK_TRAITS_ARG(3, p3) 1316 | BLK_TRAITS_ARG(4, p4) 1317 | BLK_TRAITS_ARG(5, p5) 1318 | JSValue *ret = [jsVal[@"cb"] callWithArguments:list]; 1319 | return formatJSToOC(ret); 1320 | }; 1321 | 1322 | return cb; 1323 | } 1324 | 1325 | #pragma mark - Struct 1326 | 1327 | static int sizeOfStructTypes(NSString *structTypes) 1328 | { 1329 | const char *types = [structTypes cStringUsingEncoding:NSUTF8StringEncoding]; 1330 | int index = 0; 1331 | int size = 0; 1332 | while (types[index]) { 1333 | switch (types[index]) { 1334 | #define JP_STRUCT_SIZE_CASE(_typeChar, _type) \ 1335 | case _typeChar: \ 1336 | size += sizeof(_type); \ 1337 | break; 1338 | 1339 | JP_STRUCT_SIZE_CASE('c', char) 1340 | JP_STRUCT_SIZE_CASE('C', unsigned char) 1341 | JP_STRUCT_SIZE_CASE('s', short) 1342 | JP_STRUCT_SIZE_CASE('S', unsigned short) 1343 | JP_STRUCT_SIZE_CASE('i', int) 1344 | JP_STRUCT_SIZE_CASE('I', unsigned int) 1345 | JP_STRUCT_SIZE_CASE('l', long) 1346 | JP_STRUCT_SIZE_CASE('L', unsigned long) 1347 | JP_STRUCT_SIZE_CASE('q', long long) 1348 | JP_STRUCT_SIZE_CASE('Q', unsigned long long) 1349 | JP_STRUCT_SIZE_CASE('f', float) 1350 | JP_STRUCT_SIZE_CASE('F', CGFloat) 1351 | JP_STRUCT_SIZE_CASE('N', NSInteger) 1352 | JP_STRUCT_SIZE_CASE('U', NSUInteger) 1353 | JP_STRUCT_SIZE_CASE('d', double) 1354 | JP_STRUCT_SIZE_CASE('B', BOOL) 1355 | JP_STRUCT_SIZE_CASE('*', void *) 1356 | JP_STRUCT_SIZE_CASE('^', void *) 1357 | 1358 | default: 1359 | break; 1360 | } 1361 | index ++; 1362 | } 1363 | return size; 1364 | } 1365 | 1366 | static void getStructDataWithDict(void *structData, NSDictionary *dict, NSDictionary *structDefine) 1367 | { 1368 | NSArray *itemKeys = structDefine[@"keys"]; 1369 | const char *structTypes = [structDefine[@"types"] cStringUsingEncoding:NSUTF8StringEncoding]; 1370 | int position = 0; 1371 | for (int i = 0; i < itemKeys.count; i ++) { 1372 | switch(structTypes[i]) { 1373 | #define JP_STRUCT_DATA_CASE(_typeStr, _type, _transMethod) \ 1374 | case _typeStr: { \ 1375 | int size = sizeof(_type); \ 1376 | _type val = [dict[itemKeys[i]] _transMethod]; \ 1377 | memcpy(structData + position, &val, size); \ 1378 | position += size; \ 1379 | break; \ 1380 | } 1381 | 1382 | JP_STRUCT_DATA_CASE('c', char, charValue) 1383 | JP_STRUCT_DATA_CASE('C', unsigned char, unsignedCharValue) 1384 | JP_STRUCT_DATA_CASE('s', short, shortValue) 1385 | JP_STRUCT_DATA_CASE('S', unsigned short, unsignedShortValue) 1386 | JP_STRUCT_DATA_CASE('i', int, intValue) 1387 | JP_STRUCT_DATA_CASE('I', unsigned int, unsignedIntValue) 1388 | JP_STRUCT_DATA_CASE('l', long, longValue) 1389 | JP_STRUCT_DATA_CASE('L', unsigned long, unsignedLongValue) 1390 | JP_STRUCT_DATA_CASE('q', long long, longLongValue) 1391 | JP_STRUCT_DATA_CASE('Q', unsigned long long, unsignedLongLongValue) 1392 | JP_STRUCT_DATA_CASE('f', float, floatValue) 1393 | JP_STRUCT_DATA_CASE('d', double, doubleValue) 1394 | JP_STRUCT_DATA_CASE('B', BOOL, boolValue) 1395 | JP_STRUCT_DATA_CASE('N', NSInteger, integerValue) 1396 | JP_STRUCT_DATA_CASE('U', NSUInteger, unsignedIntegerValue) 1397 | 1398 | case 'F': { 1399 | int size = sizeof(CGFloat); 1400 | CGFloat val; 1401 | #if CGFLOAT_IS_DOUBLE 1402 | val = [dict[itemKeys[i]] doubleValue]; 1403 | #else 1404 | val = [dict[itemKeys[i]] floatValue]; 1405 | #endif 1406 | memcpy(structData + position, &val, size); 1407 | position += size; 1408 | break; 1409 | } 1410 | 1411 | case '*': 1412 | case '^': { 1413 | int size = sizeof(void *); 1414 | void *val = [(JPBoxing *)dict[itemKeys[i]] unboxPointer]; 1415 | memcpy(structData + position, &val, size); 1416 | break; 1417 | } 1418 | 1419 | } 1420 | } 1421 | } 1422 | 1423 | static NSDictionary *getDictOfStruct(void *structData, NSDictionary *structDefine) 1424 | { 1425 | NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 1426 | NSArray *itemKeys = structDefine[@"keys"]; 1427 | const char *structTypes = [structDefine[@"types"] cStringUsingEncoding:NSUTF8StringEncoding]; 1428 | int position = 0; 1429 | 1430 | for (int i = 0; i < itemKeys.count; i ++) { 1431 | switch(structTypes[i]) { 1432 | #define JP_STRUCT_DICT_CASE(_typeName, _type) \ 1433 | case _typeName: { \ 1434 | size_t size = sizeof(_type); \ 1435 | _type *val = malloc(size); \ 1436 | memcpy(val, structData + position, size); \ 1437 | [dict setObject:@(*val) forKey:itemKeys[i]]; \ 1438 | free(val); \ 1439 | position += size; \ 1440 | break; \ 1441 | } 1442 | JP_STRUCT_DICT_CASE('c', char) 1443 | JP_STRUCT_DICT_CASE('C', unsigned char) 1444 | JP_STRUCT_DICT_CASE('s', short) 1445 | JP_STRUCT_DICT_CASE('S', unsigned short) 1446 | JP_STRUCT_DICT_CASE('i', int) 1447 | JP_STRUCT_DICT_CASE('I', unsigned int) 1448 | JP_STRUCT_DICT_CASE('l', long) 1449 | JP_STRUCT_DICT_CASE('L', unsigned long) 1450 | JP_STRUCT_DICT_CASE('q', long long) 1451 | JP_STRUCT_DICT_CASE('Q', unsigned long long) 1452 | JP_STRUCT_DICT_CASE('f', float) 1453 | JP_STRUCT_DICT_CASE('F', CGFloat) 1454 | JP_STRUCT_DICT_CASE('N', NSInteger) 1455 | JP_STRUCT_DICT_CASE('U', NSUInteger) 1456 | JP_STRUCT_DICT_CASE('d', double) 1457 | JP_STRUCT_DICT_CASE('B', BOOL) 1458 | 1459 | case '*': 1460 | case '^': { 1461 | size_t size = sizeof(void *); 1462 | void *val = malloc(size); 1463 | memcpy(val, structData + position, size); 1464 | [dict setObject:[JPBoxing boxPointer:val] forKey:itemKeys[i]]; 1465 | position += size; 1466 | break; 1467 | } 1468 | 1469 | } 1470 | } 1471 | return dict; 1472 | } 1473 | 1474 | static NSString *extractStructName(NSString *typeEncodeString) 1475 | { 1476 | NSArray *array = [typeEncodeString componentsSeparatedByString:@"="]; 1477 | NSString *typeString = array[0]; 1478 | int firstValidIndex = 0; 1479 | for (int i = 0; i< typeString.length; i++) { 1480 | char c = [typeString characterAtIndex:i]; 1481 | if (c == '{' || c=='_') { 1482 | firstValidIndex++; 1483 | }else { 1484 | break; 1485 | } 1486 | } 1487 | return [typeString substringFromIndex:firstValidIndex]; 1488 | } 1489 | 1490 | #pragma mark - Utils 1491 | 1492 | static NSString *trim(NSString *string) 1493 | { 1494 | return [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 1495 | } 1496 | 1497 | static BOOL blockTypeIsObject(NSString *typeString) 1498 | { 1499 | return [typeString rangeOfString:@"*"].location != NSNotFound || [typeString isEqualToString:@"id"]; 1500 | } 1501 | 1502 | static NSString *convertJPSelectorString(NSString *selectorString) 1503 | { 1504 | NSString *tmpJSMethodName = [selectorString stringByReplacingOccurrencesOfString:@"__" withString:@"-"]; 1505 | NSString *selectorName = [tmpJSMethodName stringByReplacingOccurrencesOfString:@"_" withString:@":"]; 1506 | return [selectorName stringByReplacingOccurrencesOfString:@"-" withString:@"_"]; 1507 | } 1508 | 1509 | #pragma mark - Object format 1510 | 1511 | static id formatOCToJS(id obj) 1512 | { 1513 | if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSDate class]]) { 1514 | return _autoConvert ? obj: _wrapObj([JPBoxing boxObj:obj]); 1515 | } 1516 | if ([obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:NSClassFromString(@"NSBlock")] || [obj isKindOfClass:[JSValue class]]) { 1517 | return obj; 1518 | } 1519 | return _wrapObj(obj); 1520 | } 1521 | 1522 | static id formatJSToOC(JSValue *jsval) 1523 | { 1524 | id obj = [jsval toObject]; 1525 | if (!obj || [obj isKindOfClass:[NSNull class]]) return _nilObj; 1526 | 1527 | if ([obj isKindOfClass:[JPBoxing class]]) return [obj unbox]; 1528 | if ([obj isKindOfClass:[NSArray class]]) { 1529 | NSMutableArray *newArr = [[NSMutableArray alloc] init]; 1530 | for (int i = 0; i < [(NSArray*)obj count]; i ++) { 1531 | [newArr addObject:formatJSToOC(jsval[i])]; 1532 | } 1533 | return newArr; 1534 | } 1535 | if ([obj isKindOfClass:[NSDictionary class]]) { 1536 | if (obj[@"__obj"]) { 1537 | id ocObj = [obj objectForKey:@"__obj"]; 1538 | if ([ocObj isKindOfClass:[JPBoxing class]]) return [ocObj unbox]; 1539 | return ocObj; 1540 | } 1541 | if (obj[@"__isBlock"]) { 1542 | return genCallbackBlock(jsval); 1543 | } 1544 | NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init]; 1545 | for (NSString *key in [obj allKeys]) { 1546 | [newDict setObject:formatJSToOC(jsval[key]) forKey:key]; 1547 | } 1548 | return newDict; 1549 | } 1550 | return obj; 1551 | } 1552 | 1553 | static id _formatOCToJSList(NSArray *list) 1554 | { 1555 | NSMutableArray *arr = [NSMutableArray new]; 1556 | for (id obj in list) { 1557 | [arr addObject:formatOCToJS(obj)]; 1558 | } 1559 | return arr; 1560 | } 1561 | 1562 | static NSDictionary *_wrapObj(id obj) 1563 | { 1564 | if (!obj || obj == _nilObj) { 1565 | return @{@"__isNil": @(YES)}; 1566 | } 1567 | return @{@"__obj": obj, @"__clsName": NSStringFromClass([obj isKindOfClass:[JPBoxing class]] ? [[((JPBoxing *)obj) unbox] class]: [obj class])}; 1568 | } 1569 | 1570 | static id _unboxOCObjectToJS(id obj) 1571 | { 1572 | if ([obj isKindOfClass:[NSArray class]]) { 1573 | NSMutableArray *newArr = [[NSMutableArray alloc] init]; 1574 | for (int i = 0; i < [(NSArray*)obj count]; i ++) { 1575 | [newArr addObject:_unboxOCObjectToJS(obj[i])]; 1576 | } 1577 | return newArr; 1578 | } 1579 | if ([obj isKindOfClass:[NSDictionary class]]) { 1580 | NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init]; 1581 | for (NSString *key in [obj allKeys]) { 1582 | [newDict setObject:_unboxOCObjectToJS(obj[key]) forKey:key]; 1583 | } 1584 | return newDict; 1585 | } 1586 | if ([obj isKindOfClass:[NSString class]] ||[obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:NSClassFromString(@"NSBlock")] || [obj isKindOfClass:[NSDate class]]) { 1587 | return obj; 1588 | } 1589 | return _wrapObj(obj); 1590 | } 1591 | @end 1592 | 1593 | 1594 | @implementation JPExtension 1595 | 1596 | + (void)main:(JSContext *)context{} 1597 | 1598 | + (void *)formatPointerJSToOC:(JSValue *)val 1599 | { 1600 | id obj = [val toObject]; 1601 | if ([obj isKindOfClass:[NSDictionary class]]) { 1602 | if (obj[@"__obj"] && [obj[@"__obj"] isKindOfClass:[JPBoxing class]]) { 1603 | return [(JPBoxing *)(obj[@"__obj"]) unboxPointer]; 1604 | } else { 1605 | return NULL; 1606 | } 1607 | } else if (![val toBool]) { 1608 | return NULL; 1609 | } else{ 1610 | return [((JPBoxing *)[val toObject]) unboxPointer]; 1611 | } 1612 | } 1613 | 1614 | + (id)formatRetainedCFTypeOCToJS:(CFTypeRef)CF_CONSUMED type 1615 | { 1616 | return formatOCToJS([JPBoxing boxPointer:(void *)type]); 1617 | } 1618 | 1619 | + (id)formatPointerOCToJS:(void *)pointer 1620 | { 1621 | return formatOCToJS([JPBoxing boxPointer:pointer]); 1622 | } 1623 | 1624 | + (id)formatJSToOC:(JSValue *)val 1625 | { 1626 | if (![val toBool]) { 1627 | return nil; 1628 | } 1629 | return formatJSToOC(val); 1630 | } 1631 | 1632 | + (id)formatOCToJS:(id)obj 1633 | { 1634 | return [[JSContext currentContext][@"_formatOCToJS"] callWithArguments:@[formatOCToJS(obj)]]; 1635 | } 1636 | 1637 | + (int)sizeOfStructTypes:(NSString *)structTypes 1638 | { 1639 | return sizeOfStructTypes(structTypes); 1640 | } 1641 | 1642 | + (void)getStructDataWidthDict:(void *)structData dict:(NSDictionary *)dict structDefine:(NSDictionary *)structDefine 1643 | { 1644 | return getStructDataWithDict(structData, dict, structDefine); 1645 | } 1646 | 1647 | + (NSDictionary *)getDictOfStruct:(void *)structData structDefine:(NSDictionary *)structDefine 1648 | { 1649 | return getDictOfStruct(structData, structDefine); 1650 | } 1651 | 1652 | + (NSMutableDictionary *)registeredStruct 1653 | { 1654 | return _registeredStruct; 1655 | } 1656 | 1657 | + (NSDictionary *)overideMethods 1658 | { 1659 | return _JSOverideMethods; 1660 | } 1661 | 1662 | @end 1663 | --------------------------------------------------------------------------------