├── .gitignore
├── App Plugin
├── App Plugin.xctemplate
│ ├── Info.plist
│ ├── PrefixHeader.pch
│ ├── TemplateIcon.icns
│ ├── TemplateInfo.plist
│ ├── ___PACKAGENAME___.h
│ ├── ___PACKAGENAME___.m
│ └── ___PACKAGENAME___Header.h
└── Cocoa App Plugin.xctemplate
│ ├── Info.plist
│ ├── PrefixHeader.pch
│ ├── TemplateIcon.icns
│ ├── TemplateInfo.plist
│ ├── ___PACKAGENAME___.h
│ ├── ___PACKAGENAME___.m
│ └── ___PACKAGENAME___Header.h
├── Example
└── TestPlugin
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Test.app
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboardc
│ │ │ ├── 01J-lp-oVM-view-Ze5-6b-2t3.nib
│ │ │ ├── Info.plist
│ │ │ └── UIViewController-01J-lp-oVM.nib
│ │ └── Main.storyboardc
│ │ │ ├── BYZ-38-t0r-view-8bC-Xf-vdC.nib
│ │ │ ├── Info.plist
│ │ │ └── UIViewController-BYZ-38-t0r.nib
│ ├── Info.plist
│ ├── PkgInfo
│ ├── Test
│ └── _CodeSignature
│ │ └── CodeResources
│ ├── TestPlugin.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── TestPlugin.xcworkspace
│ └── contents.xcworkspacedata
│ └── TestPlugin
│ ├── Info.plist
│ ├── PrefixHeader.pch
│ ├── TestPlugin.h
│ ├── TestPlugin.m
│ └── TestPluginHeader.h
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # svn
2 | *.svn*
3 |
4 | # mac
5 | *.DS_Store*
6 | *._*
7 | *.Spotlight-V100
8 | *.Trashes
9 | *ehthumbs.db
10 | *Thumbs.db
11 |
12 | # Xcode
13 | */build/
14 | *.pbxuser
15 | !default.pbxuser
16 | *.mode1v3
17 | !default.mode1v3
18 | *.mode2v3
19 | !default.mode2v3
20 | *.perspectivev3
21 | !default.perspectivev3
22 | xcuserdata
23 | *.xccheckout
24 | *.moved-aside
25 | DerivedData
26 | *.hmap
27 | *.ipa
28 | *.xcuserstate
29 |
30 | # generated files
31 | */bin/*
32 | */gen/*
33 |
34 | # built application files
35 | *.apk
36 | *.ap_
37 |
38 | # files for the dex VM
39 | *.dex
40 |
41 | # Java class files
42 | *.class
43 |
44 | # Local configuration file (sdk path, etc)
45 | local.properties
46 |
47 | # Eclipse project files
48 | #.classpath
49 | #.project
50 | #.settings
51 |
52 | # Proguard folder generated by Eclipse
53 | proguard/
54 |
55 | # Intellij project files
56 | *.iml
57 | *.ipr
58 | *.iws
59 | .idea/
60 |
61 | #Pod
62 | *Pods/
63 |
--------------------------------------------------------------------------------
/App Plugin/App Plugin.xctemplate/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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/App Plugin/App Plugin.xctemplate/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PROJECTNAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | //___COPYRIGHT___
7 | //
8 |
9 | #ifndef ___PACKAGENAME____PrefixHeader_pch
10 | #define ___PACKAGENAME____PrefixHeader_pch
11 |
12 | #import
13 | #import
14 | #import
15 | #import
16 |
17 | #define CBGetClass(classname) objc_getClass(#classname)
18 | #define CBRegisterClass(superclassname, subclassname) { Class class = objc_allocateClassPair(CBGetClass(superclassname), #subclassname, 0);objc_registerClassPair(class); }
19 | #define CBHookInstanceMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleMethod:ori_sel withMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
20 | #define CBHookClassMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleClassMethod:ori_sel withClassMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
21 | #define CBGetInstanceValue(obj, valuename) object_getIvar(obj, class_getInstanceVariable([obj class], #valuename))
22 | #define CBSetInstanceValue(obj, valuename, value) object_setIvar(obj, class_getInstanceVariable([obj class], #valuename), value)
23 |
24 | #endif
25 |
26 |
--------------------------------------------------------------------------------
/App Plugin/App Plugin.xctemplate/TemplateIcon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/App Plugin/App Plugin.xctemplate/TemplateIcon.icns
--------------------------------------------------------------------------------
/App Plugin/App Plugin.xctemplate/TemplateInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Kind
6 | Xcode.Xcode3.ProjectTemplateUnitKind
7 | Identifier
8 | com.corbin.pluginFramework
9 | Concrete
10 |
11 | Description
12 | This template builds a plugin framework that links against the Foundation and UIKit frameworks.
13 | Platforms
14 |
15 | com.apple.platform.iphoneos
16 |
17 | Ancestors
18 |
19 | com.apple.dt.unit.frameworkBase
20 |
21 | Project
22 |
23 | SharedSettings
24 |
25 | TARGETED_DEVICE_FAMILY
26 | 1,2
27 | GCC_WARN_ABOUT_MISSING_PROTOTYPES
28 | YES
29 | GCC_WARN_UNUSED_VARIABLE
30 | YES
31 | GCC_WARN_ABOUT_RETURN_TYPE
32 | YES
33 | GCC_C_LANGUAGE_STANDARD
34 | gnu99
35 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES
36 | *.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj
37 | IPHONEOS_DEPLOYMENT_TARGET
38 | latest_iphoneos
39 |
40 | SDK
41 | iphoneos
42 | Configurations
43 |
44 | Debug
45 |
46 | VALIDATE_PRODUCT
47 | NO
48 | GCC_OPTIMIZATION_LEVEL
49 | 0
50 | GCC_PREPROCESSOR_DEFINITIONS
51 | DEBUG=1 $(inherited)
52 | GCC_SYMBOLS_PRIVATE_EXTERN
53 | NO
54 | COPY_PHASE_STRIP
55 | NO
56 | GCC_DYNAMIC_NO_PIC
57 | NO
58 |
59 | Release
60 |
61 | COPY_PHASE_STRIP
62 | YES
63 | VALIDATE_PRODUCT
64 | YES
65 |
66 |
67 |
68 | Targets
69 |
70 |
71 | ProductType
72 | com.apple.product-type.framework
73 | TargetIdentifier
74 | plugin
75 | SharedSettings
76 |
77 | INSTALL_PATH
78 | $(LOCAL_LIBRARY_DIR)/Frameworks
79 | SKIP_INSTALL
80 | YES
81 | DYLIB_COMPATIBILITY_VERSION
82 | 1
83 | DYLIB_CURRENT_VERSION
84 | 1
85 | DYLIB_INSTALL_NAME_BASE
86 | @rpath
87 | DEFINES_MODULE
88 | YES
89 | GCC_PRECOMPILE_PREFIX_HEADER
90 | YES
91 | GCC_PREFIX_HEADER
92 | ___PACKAGENAME___/PrefixHeader.pch
93 | CODE_SIGN_IDENTITY
94 | iPhone Developer
95 |
96 | BuildPhases
97 |
98 |
99 |
100 | Name
101 | ___VARIABLE_TargetAppName___
102 | ProductType
103 | com.apple.product-type.application
104 | SharedSettings
105 |
106 | INFOPLIST_FILE
107 | ___PACKAGENAME___/Info.plist
108 | PRODUCT_NAME
109 | ___VARIABLE_TargetAppName___
110 | PRODUCT_BUNDLE_IDENTIFIER
111 | ___VARIABLE_TargetAppBundleId___
112 | DEFINES_MODULE
113 | YES
114 | GCC_PRECOMPILE_PREFIX_HEADER
115 | YES
116 | CODE_SIGN_IDENTITY
117 | iPhone Developer
118 |
119 | BuildPhases
120 |
121 |
122 | Class
123 | ShellScript
124 | ShellPath
125 | /bin/sh
126 | ShowEnvVarsInLog
127 | true
128 | ShellScript
129 | APP_PATH="${PROJECT_DIR}/___VARIABLE_TargetAppName___.app"
130 | FRAMEWORK_PATH="${BUILT_PRODUCTS_DIR}/___PACKAGENAME___.framework"
131 | BUNDLE_IDENTIFIER="___VARIABLE_TargetAppBundleId___"
132 |
133 | APP_NAME="___VARIABLE_TargetAppName___.app"
134 | APP_EXECUTABLE="___VARIABLE_TargetAppName___"
135 |
136 | FRAMEWORK_NAME=$(basename "$FRAMEWORK_PATH")
137 | FRAMEWORK_EXECUTABLE="${FRAMEWORK_NAME}/${FRAMEWORK_NAME%.*}"
138 |
139 | TEMP_DIR=$(mktemp -d)
140 | cd ${TEMP_DIR}
141 |
142 | cp -r "${APP_PATH}" ${TEMP_DIR}/
143 | mkdir -p "${APP_NAME}/Frameworks"
144 | cp -r "${FRAMEWORK_PATH}" "${APP_NAME}/Frameworks"
145 |
146 | plutil -replace CFBundleIdentifier -string ${BUNDLE_IDENTIFIER} "${APP_NAME}/Info.plist"
147 | insert_dylib --all-yes @executable_path/Frameworks/${FRAMEWORK_EXECUTABLE} "${APP_NAME}/${APP_EXECUTABLE}"
148 | mv "${APP_NAME}/${APP_EXECUTABLE}_patched" "$APP_NAME/${APP_EXECUTABLE}"
149 | chmod +x "${APP_NAME}/${APP_EXECUTABLE}"
150 |
151 | rm -rf "${APP_NAME}/PlugIns"
152 | rm -rf "${APP_NAME}/Watch"
153 |
154 | rm -rf "${BUILT_PRODUCTS_DIR}/${APP_NAME}"
155 | mv "${APP_NAME}" ${BUILT_PRODUCTS_DIR}
156 | rm -rf ${TEMP_DIR}
157 |
158 |
159 | Dependencies
160 |
161 | plugin
162 |
163 |
164 |
165 | Options
166 |
167 |
168 | Identifier
169 | TargetAppName
170 | Required
171 |
172 | Name
173 | Target App Name:
174 | Description
175 | Target App Name.
176 | Type
177 | text
178 | Placeholder
179 | AppStore
180 |
181 |
182 | Identifier
183 | TargetAppBundleId
184 | Required
185 |
186 | Name
187 | Target App Bundle Id:
188 | Description
189 | Target App Bundle Id.
190 | Type
191 | text
192 | Placeholder
193 | com.apple.appStore
194 |
195 |
196 | Nodes
197 |
198 | ___PACKAGENAME___.h
199 | ___PACKAGENAME___.m
200 | ___PACKAGENAME___Header.h
201 | PrefixHeader.pch
202 | ../Podfile
203 | Info.plist
204 |
205 | Definitions
206 |
207 | ../Podfile
208 |
209 | Group
210 |
211 | Supporting Files
212 |
213 | Path
214 | Podfile
215 | Beginning
216 | platform :ios, '8.0'
217 |
218 | target '___PACKAGENAME___' do
219 | pod 'JRSwizzle', '~> 1.0'
220 | pod 'fishhook', '~> 0.2'
221 | end
222 | End
223 |
224 |
225 | ___PACKAGENAME___.h
226 |
227 | Path
228 | ___PACKAGENAME___.h
229 |
230 | ___PACKAGENAME___.m
231 |
232 | Path
233 | ___PACKAGENAME___.m
234 |
235 | ___PACKAGENAME___Header.h
236 |
237 | Path
238 | ___PACKAGENAME___Header.h
239 |
240 | PrefixHeader.pch
241 |
242 | Group
243 |
244 | Supporting Files
245 |
246 | Path
247 | PrefixHeader.pch
248 |
249 | Info.plist
250 |
251 | Group
252 |
253 | Supporting Files
254 |
255 | Path
256 | Info.plist
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/App Plugin/App Plugin.xctemplate/___PACKAGENAME___.h:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PACKAGENAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | // Copyright (c) ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
--------------------------------------------------------------------------------
/App Plugin/App Plugin.xctemplate/___PACKAGENAME___.m:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PACKAGENAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | // Copyright (c) ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
7 | //
8 |
9 | #import "___FILEBASENAME___.h"
10 | #import "___PACKAGENAME___Header.h"
11 |
12 | #pragma mark - Plugin
13 |
14 | @implementation NSObject (___PACKAGENAME___)
15 |
16 | @end
17 |
18 | @implementation UIView (___PACKAGENAME___)
19 |
20 | @end
21 |
22 | @implementation UIViewController (___PACKAGENAME___)
23 |
24 | @end
25 |
26 | static void __attribute__((constructor)) initialize(void) {
27 | NSLog(@"++++++++ ___FILEBASENAME___ loaded ++++++++");
28 | }
--------------------------------------------------------------------------------
/App Plugin/App Plugin.xctemplate/___PACKAGENAME___Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PACKAGENAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | // Copyright (c) ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
--------------------------------------------------------------------------------
/App Plugin/Cocoa App Plugin.xctemplate/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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/App Plugin/Cocoa App Plugin.xctemplate/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PROJECTNAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | //___COPYRIGHT___
7 | //
8 |
9 | #ifndef ___PACKAGENAME____PrefixHeader_pch
10 | #define ___PACKAGENAME____PrefixHeader_pch
11 |
12 | #import
13 | #import
14 | #import
15 |
16 | #define CBGetClass(classname) objc_getClass(#classname)
17 | #define CBRegisterClass(superclassname, subclassname) { Class class = objc_allocateClassPair(CBGetClass(superclassname), #subclassname, 0);objc_registerClassPair(class); }
18 | #define CBHookInstanceMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleMethod:ori_sel withMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
19 | #define CBHookClassMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleClassMethod:ori_sel withClassMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
20 | #define CBGetInstanceValue(obj, valuename) object_getIvar(obj, class_getInstanceVariable([obj class], #valuename))
21 | #define CBSetInstanceValue(obj, valuename, value) object_setIvar(obj, class_getInstanceVariable([obj class], #valuename), value)
22 |
23 | #endif
24 |
25 |
--------------------------------------------------------------------------------
/App Plugin/Cocoa App Plugin.xctemplate/TemplateIcon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/App Plugin/Cocoa App Plugin.xctemplate/TemplateIcon.icns
--------------------------------------------------------------------------------
/App Plugin/Cocoa App Plugin.xctemplate/TemplateInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Kind
6 | Xcode.Xcode3.ProjectTemplateUnitKind
7 | Identifier
8 | com.corbin.pluginFramework-mac
9 | Concrete
10 |
11 | Description
12 | This template builds a plugin framework that links against the Foundation and UIKit frameworks.
13 | Platforms
14 |
15 | com.apple.platform.macosx
16 |
17 | Ancestors
18 |
19 | com.apple.dt.unit.frameworkBase
20 | com.apple.dt.unit.macBase
21 |
22 | Project
23 |
24 | SharedSettings
25 |
26 | TARGETED_DEVICE_FAMILY
27 | 1,2
28 | GCC_WARN_ABOUT_MISSING_PROTOTYPES
29 | YES
30 | GCC_WARN_UNUSED_VARIABLE
31 | YES
32 | GCC_WARN_ABOUT_RETURN_TYPE
33 | YES
34 | GCC_C_LANGUAGE_STANDARD
35 | gnu99
36 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES
37 | *.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj
38 |
39 | Configurations
40 |
41 | Debug
42 |
43 | VALIDATE_PRODUCT
44 | NO
45 | GCC_OPTIMIZATION_LEVEL
46 | 0
47 | GCC_PREPROCESSOR_DEFINITIONS
48 | DEBUG=1 $(inherited)
49 | GCC_SYMBOLS_PRIVATE_EXTERN
50 | NO
51 | COPY_PHASE_STRIP
52 | NO
53 | GCC_DYNAMIC_NO_PIC
54 | NO
55 |
56 | Release
57 |
58 | COPY_PHASE_STRIP
59 | YES
60 | VALIDATE_PRODUCT
61 | YES
62 |
63 |
64 |
65 | Targets
66 |
67 |
68 | ProductType
69 | com.apple.product-type.framework
70 | TargetIdentifier
71 | plugin
72 | SharedSettings
73 |
74 | INSTALL_PATH
75 | $(LOCAL_LIBRARY_DIR)/Frameworks
76 | SKIP_INSTALL
77 | YES
78 | DYLIB_COMPATIBILITY_VERSION
79 | 1
80 | DYLIB_CURRENT_VERSION
81 | 1
82 | DYLIB_INSTALL_NAME_BASE
83 | @rpath
84 | DEFINES_MODULE
85 | YES
86 | GCC_PRECOMPILE_PREFIX_HEADER
87 | YES
88 | GCC_PREFIX_HEADER
89 | ___PACKAGENAME___/PrefixHeader.pch
90 |
91 | BuildPhases
92 |
93 |
94 |
95 | Name
96 | ___VARIABLE_TargetAppName___
97 | ProductType
98 | com.apple.product-type.application
99 | SharedSettings
100 |
101 | INFOPLIST_FILE
102 | ___PACKAGENAME___/Info.plist
103 | PRODUCT_NAME
104 | ___VARIABLE_TargetAppName___
105 | DEFINES_MODULE
106 | YES
107 | GCC_PRECOMPILE_PREFIX_HEADER
108 | YES
109 |
110 | BuildPhases
111 |
112 |
113 | Class
114 | ShellScript
115 | ShellPath
116 | /bin/sh
117 | ShowEnvVarsInLog
118 | true
119 | ShellScript
120 | APP_NAME="___VARIABLE_TargetAppName___"
121 | FRAMEWORK_NAME="___PACKAGENAME___"
122 |
123 | rm -rf "${BUILT_PRODUCTS_DIR}/${APP_NAME}.app"
124 | cp -r "${PROJECT_DIR}/${APP_NAME}.app" "${BUILT_PRODUCTS_DIR}/"
125 |
126 | APP_BUNDLE_PATH="${BUILT_PRODUCTS_DIR}/${APP_NAME}.app/Contents/MacOS"
127 | APP_EXECUTABLE_PATH="${APP_BUNDLE_PATH}/${APP_NAME}"
128 |
129 | cp -r "${BUILT_PRODUCTS_DIR}/${FRAMEWORK_NAME}.framework" ${APP_BUNDLE_PATH}
130 |
131 | insert_dylib --all-yes "@loader_path/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "$APP_EXECUTABLE_PATH" "$APP_EXECUTABLE_PATH"
132 |
133 |
134 | Dependencies
135 |
136 | plugin
137 |
138 |
139 |
140 | Options
141 |
142 |
143 | Identifier
144 | TargetAppName
145 | Required
146 |
147 | Name
148 | Target App Name:
149 | Description
150 | Target App Name.
151 | Type
152 | text
153 | Placeholder
154 | AppStore
155 |
156 |
157 | Nodes
158 |
159 | ___PACKAGENAME___.h
160 | ___PACKAGENAME___.m
161 | ___PACKAGENAME___Header.h
162 | PrefixHeader.pch
163 | ../Podfile
164 | Info.plist
165 |
166 | Definitions
167 |
168 | ../Podfile
169 |
170 | Group
171 |
172 | Supporting Files
173 |
174 | Path
175 | Podfile
176 | Beginning
177 | platform :osx, '10.11'
178 |
179 | target '___PACKAGENAME___' do
180 | pod 'JRSwizzle', '~> 1.0'
181 | end
182 | End
183 |
184 |
185 | ___PACKAGENAME___.h
186 |
187 | Path
188 | ___PACKAGENAME___.h
189 |
190 | ___PACKAGENAME___.m
191 |
192 | Path
193 | ___PACKAGENAME___.m
194 |
195 | ___PACKAGENAME___Header.h
196 |
197 | Path
198 | ___PACKAGENAME___Header.h
199 |
200 | PrefixHeader.pch
201 |
202 | Group
203 |
204 | Supporting Files
205 |
206 | Path
207 | PrefixHeader.pch
208 |
209 | Info.plist
210 |
211 | Group
212 |
213 | Supporting Files
214 |
215 | Path
216 | Info.plist
217 |
218 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/App Plugin/Cocoa App Plugin.xctemplate/___PACKAGENAME___.h:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PACKAGENAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | // Copyright (c) ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
--------------------------------------------------------------------------------
/App Plugin/Cocoa App Plugin.xctemplate/___PACKAGENAME___.m:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PACKAGENAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | // Copyright (c) ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
7 | //
8 |
9 | #import "___FILEBASENAME___.h"
10 | #import "___PACKAGENAME___Header.h"
11 |
12 | #pragma mark - Plugin
13 |
14 | @implementation NSObject (___PACKAGENAME___)
15 |
16 | @end
17 |
18 | @implementation NSView (___PACKAGENAME___)
19 |
20 | @end
21 |
22 | @implementation NSViewController (___PACKAGENAME___)
23 |
24 | @end
25 |
26 | static void __attribute__((constructor)) initialize(void) {
27 | NSLog(@"++++++++ ___FILEBASENAME___ loaded ++++++++");
28 | }
--------------------------------------------------------------------------------
/App Plugin/Cocoa App Plugin.xctemplate/___PACKAGENAME___Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // ___FILENAME___
3 | // ___PACKAGENAME___
4 | //
5 | // Created by ___FULLUSERNAME___ on ___DATE___.
6 | // Copyright (c) ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
--------------------------------------------------------------------------------
/Example/TestPlugin/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '8.0'
2 |
3 | target 'TestPlugin' do
4 | pod 'JRSwizzle', '~> 1.0'
5 | pod 'fishhook', '~> 0.2'
6 | end
7 |
--------------------------------------------------------------------------------
/Example/TestPlugin/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - fishhook (0.2)
3 | - JRSwizzle (1.0)
4 |
5 | DEPENDENCIES:
6 | - fishhook (~> 0.2)
7 | - JRSwizzle (~> 1.0)
8 |
9 | SPEC CHECKSUMS:
10 | fishhook: ea19933abfe8f2f52c55fd8b6e2718467d3ebc89
11 | JRSwizzle: dd5ead5d913a0f29e7f558200165849f006bb1e3
12 |
13 | PODFILE CHECKSUM: abd12c5fc38d668ca7630a16f7b39bb17db384a3
14 |
15 | COCOAPODS: 1.2.0
16 |
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Base.lproj/LaunchScreen.storyboardc/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Base.lproj/LaunchScreen.storyboardc/Info.plist
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Base.lproj/Main.storyboardc/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Base.lproj/Main.storyboardc/Info.plist
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Info.plist
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/Test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlayshChen/XcodeAppPluginTemplate/9014d1d3b77b86f7111db3c7a8f4e46a8c26dc74/Example/TestPlugin/Test.app/Test
--------------------------------------------------------------------------------
/Example/TestPlugin/Test.app/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
8 |
9 | 1p3j7kQQGyd4PDctW3DHSsdHFVA=
10 |
11 | Base.lproj/LaunchScreen.storyboardc/Info.plist
12 |
13 | n2t8gsDpfE6XkhG31p7IQJRxTxU=
14 |
15 | Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
16 |
17 | dwBjPNAc3ySSVIpTjRUMQV0gC6k=
18 |
19 | Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib
20 |
21 | eE/O2TZDTnLzaJw1IPRxX+aKs7A=
22 |
23 | Base.lproj/Main.storyboardc/Info.plist
24 |
25 | MDrKFvFWroTb0+KEbQShBcoBvo4=
26 |
27 | Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib
28 |
29 | +OQVNsy4kqmBB/DuvGWeDrbODjs=
30 |
31 | Info.plist
32 |
33 | kbRZtbKfaWoh+uBJzTvQlhxbrVE=
34 |
35 | PkgInfo
36 |
37 | n57qDP4tZfLD1rCS43W0B4LQjzE=
38 |
39 |
40 | files2
41 |
42 | Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
43 |
44 | hash
45 |
46 | 1p3j7kQQGyd4PDctW3DHSsdHFVA=
47 |
48 | hash2
49 |
50 | eqoNaYGYsHJUQNngO5jmSYhgH4O6wCaq31bbkGRLYng=
51 |
52 |
53 | Base.lproj/LaunchScreen.storyboardc/Info.plist
54 |
55 | hash
56 |
57 | n2t8gsDpfE6XkhG31p7IQJRxTxU=
58 |
59 | hash2
60 |
61 | HyVdXMU7Ux4/KalAao30mpWOK/lEPT4gvYN09wf31cg=
62 |
63 |
64 | Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
65 |
66 | hash
67 |
68 | dwBjPNAc3ySSVIpTjRUMQV0gC6k=
69 |
70 | hash2
71 |
72 | 96gGwVNRSvx6g/7g1CSlGk5yBDq0fadCe7hXurFeZZ8=
73 |
74 |
75 | Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib
76 |
77 | hash
78 |
79 | eE/O2TZDTnLzaJw1IPRxX+aKs7A=
80 |
81 | hash2
82 |
83 | 22XLhh5AXZq2DRXdOHiabBJLDkjRBBC+qPwDvfSu+0Y=
84 |
85 |
86 | Base.lproj/Main.storyboardc/Info.plist
87 |
88 | hash
89 |
90 | MDrKFvFWroTb0+KEbQShBcoBvo4=
91 |
92 | hash2
93 |
94 | PpvapAjR62rl6Ym4E6hkTgpKmBICxTaQXeUqcpHmmqQ=
95 |
96 |
97 | Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib
98 |
99 | hash
100 |
101 | +OQVNsy4kqmBB/DuvGWeDrbODjs=
102 |
103 | hash2
104 |
105 | yRAV5uepyymANpFYbO5etNP4QC0NRMcn3R5zipqcsV4=
106 |
107 |
108 |
109 | rules
110 |
111 | ^
112 |
113 | ^.*\.lproj/
114 |
115 | optional
116 |
117 | weight
118 | 1000
119 |
120 | ^.*\.lproj/locversion.plist$
121 |
122 | omit
123 |
124 | weight
125 | 1100
126 |
127 | ^Base\.lproj/
128 |
129 | weight
130 | 1010
131 |
132 | ^version.plist$
133 |
134 |
135 | rules2
136 |
137 | .*\.dSYM($|/)
138 |
139 | weight
140 | 11
141 |
142 | ^
143 |
144 | weight
145 | 20
146 |
147 | ^(.*/)?\.DS_Store$
148 |
149 | omit
150 |
151 | weight
152 | 2000
153 |
154 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
155 |
156 | nested
157 |
158 | weight
159 | 10
160 |
161 | ^.*
162 |
163 | ^.*\.lproj/
164 |
165 | optional
166 |
167 | weight
168 | 1000
169 |
170 | ^.*\.lproj/locversion.plist$
171 |
172 | omit
173 |
174 | weight
175 | 1100
176 |
177 | ^Base\.lproj/
178 |
179 | weight
180 | 1010
181 |
182 | ^Info\.plist$
183 |
184 | omit
185 |
186 | weight
187 | 20
188 |
189 | ^PkgInfo$
190 |
191 | omit
192 |
193 | weight
194 | 20
195 |
196 | ^[^/]+$
197 |
198 | nested
199 |
200 | weight
201 | 10
202 |
203 | ^embedded\.provisionprofile$
204 |
205 | weight
206 | 20
207 |
208 | ^version\.plist$
209 |
210 | weight
211 | 20
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 18DC9D4A977DF59C2AEA92AD /* libPods-TestPlugin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F10EC0C23534B84167907F2 /* libPods-TestPlugin.a */; };
11 | 800A11801E909CAA00263C7F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 800A117F1E909CAA00263C7F /* Info.plist */; };
12 | 800A11821E909CAA00263C7F /* TestPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 800A11811E909CAA00263C7F /* TestPlugin.h */; };
13 | 800A11841E909CAA00263C7F /* TestPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 800A11831E909CAA00263C7F /* TestPlugin.m */; };
14 | 800A11861E909CAA00263C7F /* TestPluginHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 800A11851E909CAA00263C7F /* TestPluginHeader.h */; };
15 | 800A11881E909CAA00263C7F /* PrefixHeader.pch in Headers */ = {isa = PBXBuildFile; fileRef = 800A11871E909CAA00263C7F /* PrefixHeader.pch */; };
16 | 800A118A1E909CAA00263C7F /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 800A11891E909CAA00263C7F /* Podfile */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | 800A117B1E909CAA00263C7F /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = 800A116D1E909CAA00263C7F /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = 800A11751E909CAA00263C7F;
25 | remoteInfo = TestPlugin;
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXFileReference section */
30 | 2536D5D86E931C9CD1032C09 /* Pods-TestPlugin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestPlugin.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TestPlugin/Pods-TestPlugin.debug.xcconfig"; sourceTree = ""; };
31 | 5C4E6C51D1A6C8084786A621 /* Pods-TestPlugin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestPlugin.release.xcconfig"; path = "Pods/Target Support Files/Pods-TestPlugin/Pods-TestPlugin.release.xcconfig"; sourceTree = ""; };
32 | 6F10EC0C23534B84167907F2 /* libPods-TestPlugin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-TestPlugin.a"; sourceTree = BUILT_PRODUCTS_DIR; };
33 | 800A11761E909CAA00263C7F /* TestPlugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TestPlugin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
34 | 800A117A1E909CAA00263C7F /* Test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Test.app; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 800A117F1E909CAA00263C7F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
36 | 800A11811E909CAA00263C7F /* TestPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestPlugin.h; sourceTree = ""; };
37 | 800A11831E909CAA00263C7F /* TestPlugin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestPlugin.m; sourceTree = ""; };
38 | 800A11851E909CAA00263C7F /* TestPluginHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestPluginHeader.h; sourceTree = ""; };
39 | 800A11871E909CAA00263C7F /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; };
40 | 800A11891E909CAA00263C7F /* Podfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = ""; };
41 | /* End PBXFileReference section */
42 |
43 | /* Begin PBXFrameworksBuildPhase section */
44 | 800A11721E909CAA00263C7F /* Frameworks */ = {
45 | isa = PBXFrameworksBuildPhase;
46 | buildActionMask = 2147483647;
47 | files = (
48 | 18DC9D4A977DF59C2AEA92AD /* libPods-TestPlugin.a in Frameworks */,
49 | );
50 | runOnlyForDeploymentPostprocessing = 0;
51 | };
52 | CF7462966C6E17C92BE578D7 /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 2147483647;
55 | files = (
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | /* End PBXFrameworksBuildPhase section */
60 |
61 | /* Begin PBXGroup section */
62 | 3321C313F8D0D00C77236E85 /* Pods */ = {
63 | isa = PBXGroup;
64 | children = (
65 | 2536D5D86E931C9CD1032C09 /* Pods-TestPlugin.debug.xcconfig */,
66 | 5C4E6C51D1A6C8084786A621 /* Pods-TestPlugin.release.xcconfig */,
67 | );
68 | name = Pods;
69 | sourceTree = "";
70 | };
71 | 800A116C1E909CAA00263C7F = {
72 | isa = PBXGroup;
73 | children = (
74 | 800A117D1E909CAA00263C7F /* TestPlugin */,
75 | 800A11771E909CAA00263C7F /* Products */,
76 | 3321C313F8D0D00C77236E85 /* Pods */,
77 | F8C10F3C556717356686FDDE /* Frameworks */,
78 | );
79 | sourceTree = "";
80 | };
81 | 800A11771E909CAA00263C7F /* Products */ = {
82 | isa = PBXGroup;
83 | children = (
84 | 800A11761E909CAA00263C7F /* TestPlugin.framework */,
85 | 800A117A1E909CAA00263C7F /* Test.app */,
86 | );
87 | name = Products;
88 | sourceTree = "";
89 | };
90 | 800A117D1E909CAA00263C7F /* TestPlugin */ = {
91 | isa = PBXGroup;
92 | children = (
93 | 800A11811E909CAA00263C7F /* TestPlugin.h */,
94 | 800A11831E909CAA00263C7F /* TestPlugin.m */,
95 | 800A11851E909CAA00263C7F /* TestPluginHeader.h */,
96 | 800A117E1E909CAA00263C7F /* Supporting Files */,
97 | );
98 | path = TestPlugin;
99 | sourceTree = "";
100 | };
101 | 800A117E1E909CAA00263C7F /* Supporting Files */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 800A117F1E909CAA00263C7F /* Info.plist */,
105 | 800A11871E909CAA00263C7F /* PrefixHeader.pch */,
106 | 800A11891E909CAA00263C7F /* Podfile */,
107 | );
108 | name = "Supporting Files";
109 | sourceTree = "";
110 | };
111 | F8C10F3C556717356686FDDE /* Frameworks */ = {
112 | isa = PBXGroup;
113 | children = (
114 | 6F10EC0C23534B84167907F2 /* libPods-TestPlugin.a */,
115 | );
116 | name = Frameworks;
117 | sourceTree = "";
118 | };
119 | /* End PBXGroup section */
120 |
121 | /* Begin PBXHeadersBuildPhase section */
122 | 800A11731E909CAA00263C7F /* Headers */ = {
123 | isa = PBXHeadersBuildPhase;
124 | buildActionMask = 2147483647;
125 | files = (
126 | 800A11861E909CAA00263C7F /* TestPluginHeader.h in Headers */,
127 | 800A11821E909CAA00263C7F /* TestPlugin.h in Headers */,
128 | 800A11881E909CAA00263C7F /* PrefixHeader.pch in Headers */,
129 | );
130 | runOnlyForDeploymentPostprocessing = 0;
131 | };
132 | /* End PBXHeadersBuildPhase section */
133 |
134 | /* Begin PBXNativeTarget section */
135 | 800A11751E909CAA00263C7F /* TestPlugin */ = {
136 | isa = PBXNativeTarget;
137 | buildConfigurationList = 800A118D1E909CAA00263C7F /* Build configuration list for PBXNativeTarget "TestPlugin" */;
138 | buildPhases = (
139 | EE63407BFA7688E0E803408A /* [CP] Check Pods Manifest.lock */,
140 | 800A11711E909CAA00263C7F /* Sources */,
141 | 800A11721E909CAA00263C7F /* Frameworks */,
142 | 800A11731E909CAA00263C7F /* Headers */,
143 | 800A11741E909CAA00263C7F /* Resources */,
144 | 1849EB0A85ED5E45EAA5DBD8 /* [CP] Copy Pods Resources */,
145 | );
146 | buildRules = (
147 | );
148 | dependencies = (
149 | );
150 | name = TestPlugin;
151 | productName = TestPlugin;
152 | productReference = 800A11761E909CAA00263C7F /* TestPlugin.framework */;
153 | productType = "com.apple.product-type.framework";
154 | };
155 | 800A11791E909CAA00263C7F /* Test */ = {
156 | isa = PBXNativeTarget;
157 | buildConfigurationList = 800A11901E909CAA00263C7F /* Build configuration list for PBXNativeTarget "Test" */;
158 | buildPhases = (
159 | 800A11781E909CAA00263C7F /* ShellScript */,
160 | CF7462966C6E17C92BE578D7 /* Frameworks */,
161 | );
162 | buildRules = (
163 | );
164 | dependencies = (
165 | 800A117C1E909CAA00263C7F /* PBXTargetDependency */,
166 | );
167 | name = Test;
168 | productName = Test;
169 | productReference = 800A117A1E909CAA00263C7F /* Test.app */;
170 | productType = "com.apple.product-type.application";
171 | };
172 | /* End PBXNativeTarget section */
173 |
174 | /* Begin PBXProject section */
175 | 800A116D1E909CAA00263C7F /* Project object */ = {
176 | isa = PBXProject;
177 | attributes = {
178 | LastUpgradeCheck = 0820;
179 | ORGANIZATIONNAME = CorbinChen;
180 | TargetAttributes = {
181 | 800A11751E909CAA00263C7F = {
182 | CreatedOnToolsVersion = 8.2;
183 | ProvisioningStyle = Automatic;
184 | };
185 | 800A11791E909CAA00263C7F = {
186 | CreatedOnToolsVersion = 8.2;
187 | DevelopmentTeam = TW89Q8SE37;
188 | ProvisioningStyle = Automatic;
189 | };
190 | };
191 | };
192 | buildConfigurationList = 800A11701E909CAA00263C7F /* Build configuration list for PBXProject "TestPlugin" */;
193 | compatibilityVersion = "Xcode 3.2";
194 | developmentRegion = English;
195 | hasScannedForEncodings = 0;
196 | knownRegions = (
197 | en,
198 | );
199 | mainGroup = 800A116C1E909CAA00263C7F;
200 | productRefGroup = 800A11771E909CAA00263C7F /* Products */;
201 | projectDirPath = "";
202 | projectRoot = "";
203 | targets = (
204 | 800A11751E909CAA00263C7F /* TestPlugin */,
205 | 800A11791E909CAA00263C7F /* Test */,
206 | );
207 | };
208 | /* End PBXProject section */
209 |
210 | /* Begin PBXResourcesBuildPhase section */
211 | 800A11741E909CAA00263C7F /* Resources */ = {
212 | isa = PBXResourcesBuildPhase;
213 | buildActionMask = 2147483647;
214 | files = (
215 | 800A118A1E909CAA00263C7F /* Podfile in Resources */,
216 | 800A11801E909CAA00263C7F /* Info.plist in Resources */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | /* End PBXResourcesBuildPhase section */
221 |
222 | /* Begin PBXShellScriptBuildPhase section */
223 | 1849EB0A85ED5E45EAA5DBD8 /* [CP] Copy Pods Resources */ = {
224 | isa = PBXShellScriptBuildPhase;
225 | buildActionMask = 2147483647;
226 | files = (
227 | );
228 | inputPaths = (
229 | );
230 | name = "[CP] Copy Pods Resources";
231 | outputPaths = (
232 | );
233 | runOnlyForDeploymentPostprocessing = 0;
234 | shellPath = /bin/sh;
235 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TestPlugin/Pods-TestPlugin-resources.sh\"\n";
236 | showEnvVarsInLog = 0;
237 | };
238 | 800A11781E909CAA00263C7F /* ShellScript */ = {
239 | isa = PBXShellScriptBuildPhase;
240 | buildActionMask = 2147483647;
241 | files = (
242 | );
243 | inputPaths = (
244 | );
245 | outputPaths = (
246 | );
247 | runOnlyForDeploymentPostprocessing = 0;
248 | shellPath = /bin/sh;
249 | shellScript = "APP_PATH=\"${PROJECT_DIR}/Test.app\"\nFRAMEWORK_PATH=\"${BUILT_PRODUCTS_DIR}/TestPlugin.framework\"\nBUNDLE_IDENTIFIER=\"com.corbin.Test\"\n\nAPP_NAME=\"Test.app\"\nAPP_EXECUTABLE=\"Test\"\n\nFRAMEWORK_NAME=$(basename \"$FRAMEWORK_PATH\")\nFRAMEWORK_EXECUTABLE=\"${FRAMEWORK_NAME}/${FRAMEWORK_NAME%.*}\"\n\nTEMP_DIR=$(mktemp -d)\ncd ${TEMP_DIR}\n\ncp -r \"${APP_PATH}\" ${TEMP_DIR}/\nmkdir -p \"${APP_NAME}/Frameworks\"\ncp -r \"${FRAMEWORK_PATH}\" \"${APP_NAME}/Frameworks\"\n\nplutil -replace CFBundleIdentifier -string ${BUNDLE_IDENTIFIER} \"${APP_NAME}/Info.plist\"\ninsert_dylib --all-yes @executable_path/Frameworks/${FRAMEWORK_EXECUTABLE} \"${APP_NAME}/${APP_EXECUTABLE}\"\nmv \"${APP_NAME}/${APP_EXECUTABLE}_patched\" \"$APP_NAME/${APP_EXECUTABLE}\"\nchmod +x \"${APP_NAME}/${APP_EXECUTABLE}\"\n\nrm -rf \"${APP_NAME}/PlugIns\"\nrm -rf \"${APP_NAME}/Watch\"\n\nrm -rf \"${BUILT_PRODUCTS_DIR}/${APP_NAME}\"\nmv \"${APP_NAME}\" ${BUILT_PRODUCTS_DIR}\nrm -rf ${TEMP_DIR}";
250 | };
251 | EE63407BFA7688E0E803408A /* [CP] Check Pods Manifest.lock */ = {
252 | isa = PBXShellScriptBuildPhase;
253 | buildActionMask = 2147483647;
254 | files = (
255 | );
256 | inputPaths = (
257 | );
258 | name = "[CP] Check Pods Manifest.lock";
259 | outputPaths = (
260 | );
261 | runOnlyForDeploymentPostprocessing = 0;
262 | shellPath = /bin/sh;
263 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
264 | showEnvVarsInLog = 0;
265 | };
266 | /* End PBXShellScriptBuildPhase section */
267 |
268 | /* Begin PBXSourcesBuildPhase section */
269 | 800A11711E909CAA00263C7F /* Sources */ = {
270 | isa = PBXSourcesBuildPhase;
271 | buildActionMask = 2147483647;
272 | files = (
273 | 800A11841E909CAA00263C7F /* TestPlugin.m in Sources */,
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | };
277 | /* End PBXSourcesBuildPhase section */
278 |
279 | /* Begin PBXTargetDependency section */
280 | 800A117C1E909CAA00263C7F /* PBXTargetDependency */ = {
281 | isa = PBXTargetDependency;
282 | target = 800A11751E909CAA00263C7F /* TestPlugin */;
283 | targetProxy = 800A117B1E909CAA00263C7F /* PBXContainerItemProxy */;
284 | };
285 | /* End PBXTargetDependency section */
286 |
287 | /* Begin XCBuildConfiguration section */
288 | 800A118B1E909CAA00263C7F /* Debug */ = {
289 | isa = XCBuildConfiguration;
290 | buildSettings = {
291 | ALWAYS_SEARCH_USER_PATHS = NO;
292 | CLANG_ANALYZER_NONNULL = YES;
293 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
294 | CLANG_CXX_LIBRARY = "libc++";
295 | CLANG_ENABLE_MODULES = YES;
296 | CLANG_ENABLE_OBJC_ARC = YES;
297 | CLANG_WARN_BOOL_CONVERSION = YES;
298 | CLANG_WARN_CONSTANT_CONVERSION = YES;
299 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
300 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
301 | CLANG_WARN_EMPTY_BODY = YES;
302 | CLANG_WARN_ENUM_CONVERSION = YES;
303 | CLANG_WARN_INFINITE_RECURSION = YES;
304 | CLANG_WARN_INT_CONVERSION = YES;
305 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
306 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
307 | CLANG_WARN_UNREACHABLE_CODE = YES;
308 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
309 | COPY_PHASE_STRIP = NO;
310 | CURRENT_PROJECT_VERSION = 1;
311 | DEBUG_INFORMATION_FORMAT = dwarf;
312 | ENABLE_STRICT_OBJC_MSGSEND = YES;
313 | ENABLE_TESTABILITY = YES;
314 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj";
315 | GCC_C_LANGUAGE_STANDARD = gnu99;
316 | GCC_DYNAMIC_NO_PIC = NO;
317 | GCC_NO_COMMON_BLOCKS = YES;
318 | GCC_OPTIMIZATION_LEVEL = 0;
319 | GCC_PREPROCESSOR_DEFINITIONS = (
320 | "DEBUG=1",
321 | "$(inherited)",
322 | );
323 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
325 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
326 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
327 | GCC_WARN_UNDECLARED_SELECTOR = YES;
328 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
329 | GCC_WARN_UNUSED_FUNCTION = YES;
330 | GCC_WARN_UNUSED_VARIABLE = YES;
331 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
332 | MTL_ENABLE_DEBUG_INFO = YES;
333 | ONLY_ACTIVE_ARCH = YES;
334 | SDKROOT = iphoneos;
335 | TARGETED_DEVICE_FAMILY = "1,2";
336 | VALIDATE_PRODUCT = NO;
337 | VERSIONING_SYSTEM = "apple-generic";
338 | VERSION_INFO_PREFIX = "";
339 | };
340 | name = Debug;
341 | };
342 | 800A118C1E909CAA00263C7F /* Release */ = {
343 | isa = XCBuildConfiguration;
344 | buildSettings = {
345 | ALWAYS_SEARCH_USER_PATHS = NO;
346 | CLANG_ANALYZER_NONNULL = YES;
347 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
348 | CLANG_CXX_LIBRARY = "libc++";
349 | CLANG_ENABLE_MODULES = YES;
350 | CLANG_ENABLE_OBJC_ARC = YES;
351 | CLANG_WARN_BOOL_CONVERSION = YES;
352 | CLANG_WARN_CONSTANT_CONVERSION = YES;
353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
354 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
355 | CLANG_WARN_EMPTY_BODY = YES;
356 | CLANG_WARN_ENUM_CONVERSION = YES;
357 | CLANG_WARN_INFINITE_RECURSION = YES;
358 | CLANG_WARN_INT_CONVERSION = YES;
359 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
360 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
361 | CLANG_WARN_UNREACHABLE_CODE = YES;
362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
363 | COPY_PHASE_STRIP = YES;
364 | CURRENT_PROJECT_VERSION = 1;
365 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
366 | ENABLE_NS_ASSERTIONS = NO;
367 | ENABLE_STRICT_OBJC_MSGSEND = YES;
368 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj";
369 | GCC_C_LANGUAGE_STANDARD = gnu99;
370 | GCC_NO_COMMON_BLOCKS = YES;
371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
372 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
373 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
374 | GCC_WARN_UNDECLARED_SELECTOR = YES;
375 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
376 | GCC_WARN_UNUSED_FUNCTION = YES;
377 | GCC_WARN_UNUSED_VARIABLE = YES;
378 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
379 | MTL_ENABLE_DEBUG_INFO = NO;
380 | SDKROOT = iphoneos;
381 | TARGETED_DEVICE_FAMILY = "1,2";
382 | VALIDATE_PRODUCT = YES;
383 | VERSIONING_SYSTEM = "apple-generic";
384 | VERSION_INFO_PREFIX = "";
385 | };
386 | name = Release;
387 | };
388 | 800A118E1E909CAA00263C7F /* Debug */ = {
389 | isa = XCBuildConfiguration;
390 | baseConfigurationReference = 2536D5D86E931C9CD1032C09 /* Pods-TestPlugin.debug.xcconfig */;
391 | buildSettings = {
392 | CODE_SIGN_IDENTITY = "iPhone Developer";
393 | DEFINES_MODULE = YES;
394 | DEVELOPMENT_TEAM = "";
395 | DYLIB_COMPATIBILITY_VERSION = 1;
396 | DYLIB_CURRENT_VERSION = 1;
397 | DYLIB_INSTALL_NAME_BASE = "@rpath";
398 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
399 | GCC_PREFIX_HEADER = TestPlugin/PrefixHeader.pch;
400 | INFOPLIST_FILE = TestPlugin/Info.plist;
401 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
402 | PRODUCT_BUNDLE_IDENTIFIER = com.corbin.TestPlugin;
403 | PRODUCT_NAME = "$(TARGET_NAME)";
404 | SKIP_INSTALL = YES;
405 | };
406 | name = Debug;
407 | };
408 | 800A118F1E909CAA00263C7F /* Release */ = {
409 | isa = XCBuildConfiguration;
410 | baseConfigurationReference = 5C4E6C51D1A6C8084786A621 /* Pods-TestPlugin.release.xcconfig */;
411 | buildSettings = {
412 | CODE_SIGN_IDENTITY = "iPhone Developer";
413 | DEFINES_MODULE = YES;
414 | DEVELOPMENT_TEAM = "";
415 | DYLIB_COMPATIBILITY_VERSION = 1;
416 | DYLIB_CURRENT_VERSION = 1;
417 | DYLIB_INSTALL_NAME_BASE = "@rpath";
418 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
419 | GCC_PREFIX_HEADER = TestPlugin/PrefixHeader.pch;
420 | INFOPLIST_FILE = TestPlugin/Info.plist;
421 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
422 | PRODUCT_BUNDLE_IDENTIFIER = com.corbin.TestPlugin;
423 | PRODUCT_NAME = "$(TARGET_NAME)";
424 | SKIP_INSTALL = YES;
425 | };
426 | name = Release;
427 | };
428 | 800A11911E909CAA00263C7F /* Debug */ = {
429 | isa = XCBuildConfiguration;
430 | buildSettings = {
431 | CODE_SIGN_IDENTITY = "iPhone Developer";
432 | DEFINES_MODULE = YES;
433 | DEVELOPMENT_TEAM = TW89Q8SE37;
434 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
435 | INFOPLIST_FILE = TestPlugin/Info.plist;
436 | PRODUCT_BUNDLE_IDENTIFIER = com.corbin.Test;
437 | PRODUCT_NAME = Test;
438 | };
439 | name = Debug;
440 | };
441 | 800A11921E909CAA00263C7F /* Release */ = {
442 | isa = XCBuildConfiguration;
443 | buildSettings = {
444 | CODE_SIGN_IDENTITY = "iPhone Developer";
445 | DEFINES_MODULE = YES;
446 | DEVELOPMENT_TEAM = TW89Q8SE37;
447 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
448 | INFOPLIST_FILE = TestPlugin/Info.plist;
449 | PRODUCT_BUNDLE_IDENTIFIER = com.corbin.Test;
450 | PRODUCT_NAME = Test;
451 | };
452 | name = Release;
453 | };
454 | /* End XCBuildConfiguration section */
455 |
456 | /* Begin XCConfigurationList section */
457 | 800A11701E909CAA00263C7F /* Build configuration list for PBXProject "TestPlugin" */ = {
458 | isa = XCConfigurationList;
459 | buildConfigurations = (
460 | 800A118B1E909CAA00263C7F /* Debug */,
461 | 800A118C1E909CAA00263C7F /* Release */,
462 | );
463 | defaultConfigurationIsVisible = 0;
464 | defaultConfigurationName = Release;
465 | };
466 | 800A118D1E909CAA00263C7F /* Build configuration list for PBXNativeTarget "TestPlugin" */ = {
467 | isa = XCConfigurationList;
468 | buildConfigurations = (
469 | 800A118E1E909CAA00263C7F /* Debug */,
470 | 800A118F1E909CAA00263C7F /* Release */,
471 | );
472 | defaultConfigurationIsVisible = 0;
473 | defaultConfigurationName = Release;
474 | };
475 | 800A11901E909CAA00263C7F /* Build configuration list for PBXNativeTarget "Test" */ = {
476 | isa = XCConfigurationList;
477 | buildConfigurations = (
478 | 800A11911E909CAA00263C7F /* Debug */,
479 | 800A11921E909CAA00263C7F /* Release */,
480 | );
481 | defaultConfigurationIsVisible = 0;
482 | defaultConfigurationName = Release;
483 | };
484 | /* End XCConfigurationList section */
485 | };
486 | rootObject = 800A116D1E909CAA00263C7F /* Project object */;
487 | }
488 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin/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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // PrefixHeader.pch
3 | // TestPlugin
4 | //
5 | // Created by CorbinChen on 2017/4/2.
6 | // Copyright © 2017年 CorbinChen. All rights reserved.
7 | //
8 |
9 | #ifndef TestPlugin_PrefixHeader_pch
10 | #define TestPlugin_PrefixHeader_pch
11 |
12 | #import
13 | #import
14 | #import
15 | #import
16 |
17 | #define CBGetClass(classname) objc_getClass(#classname)
18 | #define CBRegisterClass(superclassname, subclassname) { Class class = objc_allocateClassPair(CBGetClass(superclassname), #subclassname, 0);objc_registerClassPair(class); }
19 | #define CBHookInstanceMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleMethod:ori_sel withMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
20 | #define CBHookClassMethod(classname, ori_sel, new_sel) { NSError *error; [CBGetClass(classname) jr_swizzleClassMethod:ori_sel withClassMethod:new_sel error:&error]; if(error) NSLog(@"%@", error); }
21 | #define CBGetInstanceValue(obj, valuename) object_getIvar(obj, class_getInstanceVariable([obj class], #valuename))
22 | #define CBSetInstanceValue(obj, valuename, value) object_setIvar(obj, class_getInstanceVariable([obj class], #valuename), value)
23 |
24 | #endif
25 |
26 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin/TestPlugin.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestPlugin.h
3 | // TestPlugin
4 | //
5 | // Created by CorbinChen on 2017/4/2.
6 | // Copyright (c) 2017年 CorbinChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin/TestPlugin.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestPlugin.m
3 | // TestPlugin
4 | //
5 | // Created by CorbinChen on 2017/4/2.
6 | // Copyright (c) 2017年 CorbinChen. All rights reserved.
7 | //
8 |
9 | #import "TestPlugin.h"
10 | #import "TestPluginHeader.h"
11 |
12 | #pragma mark - Plugin
13 |
14 | @implementation NSObject (TestPlugin)
15 |
16 | @end
17 |
18 | @implementation UIView (TestPlugin)
19 |
20 | @end
21 |
22 | @implementation UIViewController (TestPlugin)
23 |
24 | - (void)cb_viewDidLoad {
25 | [self cb_viewDidLoad];
26 | self.view.backgroundColor = [UIColor orangeColor];
27 | }
28 |
29 | @end
30 |
31 | static void __attribute__((constructor)) initialize(void) {
32 | NSLog(@"++++++++ TestPlugin loaded ++++++++");
33 | CBHookInstanceMethod(UIViewController, @selector(viewDidLoad), @selector(cb_viewDidLoad));
34 | }
35 |
--------------------------------------------------------------------------------
/Example/TestPlugin/TestPlugin/TestPluginHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestPluginHeader.h
3 | // TestPlugin
4 | //
5 | // Created by CorbinChen on 2017/4/2.
6 | // Copyright (c) 2017年 CorbinChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # XcodeAppPluginTemplate
2 |
3 | 
4 | App Plugin Project Template For iOS App and Mac App.
5 |
6 | 说明:我将过去文章中涉及到的工程整理出工程模版,方便对第三方app进行hook.
7 | 文章链接:[我是如何利用Xcode调试开发微信消息预览插件的](http://alayshchen.github.io/2016/02/26/我是如何利用Xcode调试开发微信消息预览插件的/)
8 |
9 | ## 前提
10 |
11 | [insert_dylib](https://github.com/Tyilo/insert_dylib)
12 |
13 |
14 | ## 如何安装
15 |
16 | * 将 `App Plugin` 文件夹拷贝到 `~/Library/Developer/Xcode/Templates/Project Templates`.
17 |
18 | ## 如何卸载
19 |
20 | * 删除文件夹:`~/Library/Developer/Xcode/Templates/Project Templates/App Plugin`.
21 |
22 | ## 如何使用
23 |
24 | * 在Xcode中选择新建工程,选择iOS中的`App Plugin`或者macOS中的`Mac App Plugin`工程模版.
25 |
26 | 
27 |
28 | * 填写工程选项.(Target app name 是要hook的第三方app名称,Target app bundle id打包后的app bundle id, 脚本会自动修改原app bundle id为此值)
29 |
30 | 
31 |
32 | * 最后,将要hook的app放在工程文件夹中,注意这里的文件名要与上一步中的Target app name一致,并执行命令`pod install`.
33 |
34 | 
35 |
36 |
37 | ## 原理
38 | 使用模版创建工程后,会有一个动态库target和空app target. 选择app scheme进行build,Xcode首先会build 动态库,然后执行脚本,将动态库注入app中,生成新的app,放在product目录。接着Xcode会进行签名等一系列操作,启动app,连接调试器,这样,我们就可以debug插件和原app了。
39 |
40 | * 注入动态库
41 | 
42 | * Xcode Build流程
43 | 
44 | * 效果图
45 | 
46 |
--------------------------------------------------------------------------------