生成Xcode templete,自动化注入工程配置

生成Xcode templete,自动化注入工程配置

上一篇: 动态库注入及在非越狱手机使用

上一篇已经讲解了如何生成包含动态库的工程并自动注入APP安装到设备上。但是,每次新建项目,配置各种环境,稍显麻烦。

本篇主要讲解如何生成Xcode 模板,直接从模板中生成项目,效果图如下

在这里插入图片描述

主要包含两个template,一个是生成动态库的template,另外一个是生成app关联动态库的. NoahDevApp 创建的项目工程如下。
在这里插入图片描述

与手动生成的基本一致。

步骤如下

这里几个目录可以了解下

    1. Xcode iOS 项目template目录
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates
    1. Xcode自定义模板目录
~/Library/Developer/Xcode/Templates
    1. Xcode macOS项目template目录
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates

我们之后生成的模板就放在自定义模板目录下

开始生成自定义动态库模板

1. 先看看系统模板里面怎么配置的

直接打开 Single View App.xctemplate,发现主要是TemplateInfo.plist这个文件

在这里插入图片描述

话不多说,直接复制整个 Single View App.xctemplate到自定义目录

我们现在自定义模板目录新建一个目录,叫 Custom ,然后把 Single View App.xctemplate放到他里面

试试Xcode新建项目,发现多了一个Custom段,底下还有Single View App 这么一个模板,这就是我们刚刚复制过来的。他与系统的Single View App没什么区别,下面就来修改一下。

在这里插入图片描述

2. 修改自定义模板配置

打开TemplateInfo.plist 文件,改下 Identifiier字段,否则系统的就被覆盖掉了

在这里插入图片描述

我们需要修改的字段截图如下

在这里插入图片描述

几个主要的字段解释:

  • identifiier: 跟咱们工程的BundleIdentifier是一样的,用来标志应用的唯一性,所以不要用跟系统模板一样的,否则系统模板就找不到了。
  • Ancestors: 这是父模板,系统已经存在的模板都是有继承关系的,跟类的继承类似。
  • Nodes: 这是我们要引入的文件或者Group定义,比如当前项目生成的时候有AppDelegate类与ViewController类,这些可以在Nodes中引入
  • Definitions: 与Nodes字段关联的字段,Nodes字段中定义的类或者Group,要在当前字段中指明path和Group,未定义Path的则不会被模板引入。未定义Group的则是默认项目所在的Group
  • Targets: 与Xcode中的Target含义一致,里面可以做一些target的配置
  • Project: 与Xocde中的Project含义一致,里面可以做一些工程相关的配置
  • Components: 表示依赖关系,例如需要引入一个子项目

3. 生成一个动态库模板配置

我们的项目需要一个动态库的target,所以先弄一个动态库的模板,设定好需要修改的配置

1) 直接找到系统的动态库模板

在这里插入图片描述

2) 拷贝到自定义模板目录下

在这里插入图片描述

3) 生成library的初始文件,直接拿Cocoa___PACKAGENAMEASIDENTIFIER___类修改即可, 将类文件中的内容清空

在这里插入图片描述

4) 修改target配置,工程配置

在这里插入图片描述

在这里插入图片描述

Other_LDFLAGS: 即为Other Linker Flags字段
具体内容如下:

$(inherited)  -weak_library /usr/lib/libc++.dylib -weak_library /usr/lib/libstdc++.dylib -weak_library /opt/NoahDev/Dylibs/libsubstrate.dylib -weak_library /opt/NoahDev/Dylibs/libcycript.dylib

5) 配置初始文件路径
动态库的配置采用另外一种方式,主要内容在红框中

在这里插入图片描述

6) 生成一个项目试试

在这里插入图片描述

TemplateInfo.plist的内容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Kind</key>
	<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>
	<key>Identifier</key>
	<string>com.apple.dt.unit.osxLibrary.custom</string>
	<key>Ancestors</key>
	<array>
		<string>com.apple.dt.unit.base</string>
		<string>com.apple.dt.unit.iosBase</string>
	</array>
	<key>Concrete</key>
	<true/>
	<key>Description</key>
	<string>This template builds a library configured for iOS tweak.</string>
	<key>SortOrder</key>
	<integer>10</integer>
	<key>Targets</key>
	<array>
		<dict>
			<key>Frameworks</key>
			<array>
				<string>Foundation</string>
				<string>UIKit</string>
			</array>
			<key>TargetIdentifier</key>
			<string>com.apple.dt.macosLibraryOrFrameworkTarget</string>
			<key>SharedSettings</key>
			<dict>
				<key>ENABLE_BITCODE</key>
				<string>NO</string>
				<key>EXECUTABLE_PREFIX</key>
				<string>lib</string>
				<key>SKIP_INSTALL</key>
				<string>NO</string>
			</dict>
			<key>BuildPhases</key>
			<array>
				<dict>
					<key>Class</key>
					<string>Headers</string>
				</dict>
				<dict>
					<key>Class</key>
					<string>Sources</string>
				</dict>
				<dict>
					<key>Class</key>
					<string>Frameworks</string>
				</dict>
				<dict>
					<key>RunOnlyForDeploymentPostprocessing</key>
					<false/>
					<key>Class</key>
					<string>ShellScript</string>
					<key>ShellPath</key>
					<string>/bin/sh</string>
					<key>ShellScript</key>
					<string>/opt/NoahDev/bin/dylib.sh</string>
				</dict>
			</array>
		</dict>
	</array>
	<key>Options</key>
	<array>
		<dict>
			<key>Identifier</key>
			<string>libraryFramework</string>
			<key>Name</key>
			<string>Framework:</string>
			<key>Description</key>
			<string>What system framework the library will be based on</string>
			<key>Type</key>
			<string>popup</string>
			<key>Values</key>
			<array>
				<string>iOSTweak</string>
			</array>
			<key>Default</key>
			<string>iOSTweak</string>
			<key>Units</key>
			<dict>
				<key>iOSTweak</key>
				<array>
					<dict>
						<key>Nodes</key>
						<array>
							<string>___PACKAGENAMEASIDENTIFIER___.xm</string>
							<string>___PACKAGENAMEASIDENTIFIER___.mm</string>
						</array>
						<key>Definitions</key>
						<dict>
							<key>___PACKAGENAMEASIDENTIFIER___.xm</key>
							<dict>
								<key>Path</key>
								<string>iOSTweak___PACKAGENAMEASIDENTIFIER___.xm</string>
							</dict>
							<key>___PACKAGENAMEASIDENTIFIER___.mm</key>
							<dict>
								<key>Path</key>
								<string>iOSTweak___PACKAGENAMEASIDENTIFIER___.mm</string>
							</dict>
						</dict>
					</dict>
				</array>
			</dict>
		</dict>
		<dict>
			<key>Identifier</key>
			<string>libraryType</string>
			<key>Name</key>
			<string>Type:</string>
			<key>Description</key>
			<string>Which type of library to create</string>
			<key>Type</key>
			<string>popup</string>
			<key>Default</key>
			<string>Dynamic</string>
			<key>Units</key>
			<dict>
				<key>Dynamic</key>
				<array>
					<dict>
						<key>Targets</key>
						<array>
							<dict>
								<key>ProductType</key>
								<string>com.apple.product-type.library.dynamic</string>
								<key>SharedSettings</key>
								<dict>
									<key>DYLIB_COMPATIBILITY_VERSION</key>
									<string>1</string>
									<key>DYLIB_CURRENT_VERSION</key>
									<string>1</string>
								</dict>
							</dict>
						</array>
					</dict>
				</array>
				<key>Static</key>
				<array>
					<dict>
						<key>Targets</key>
						<array>
							<dict>
								<key>ProductType</key>
								<string>com.apple.product-type.library.static</string>
							</dict>
						</array>
					</dict>
				</array>
			</dict>
		</dict>
	</array>
	<key>Project</key>
	<dict>
		<key>SharedSettings</key>
		<dict>
			<key>HEADER_SEARCH_PATHS</key>
			<string>/opt/NoahDev/include/**</string>
			<key>OTHER_LDFLAGS</key>
			<string>$(inherited)  -weak_library /usr/lib/libc++.dylib -weak_library /usr/lib/libstdc++.dylib -weak_library /opt/NoahDev/Dylibs/libsubstrate.dylib -weak_library /opt/NoahDev/Dylibs/libcycript.dylib</string>
			<key>IPHONEOS_DEPLOYMENT_TARGET</key>
			<string>8.0</string>
		</dict>
	</dict>
	<key>Nodes</key>
	<array/>
</dict>
</plist>

开始生成自定义App模板

1) 修改自定义模板下Single View App模板的 Identifier

在这里插入图片描述

2)修改Components依赖之前生成的动态库

在这里插入图片描述

3)修改target配置与工程配置

在这里插入图片描述

4)配置初始文件及Group

在这里插入图片描述

5)修改继承关系

在这里插入图片描述

6)修改storyboard使他支持 iOS8.0

在这里插入图片描述

在这里插入图片描述

7)创建APP,查看效果

在这里插入图片描述

TemplateInfo.plist 内容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Platforms</key>
	<array>
		<string>com.apple.platform.iphoneos</string>
	</array>
	<key>Kind</key>
	<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>
	<key>Identifier</key>
	<string>com.apple.dt.unit.noahDevApp</string>
	<key>Ancestors</key>
	<array>
		<string>com.apple.dt.unit.noahdev.cocoaTouchApplicationBase</string>
		<string>com.apple.dt.unit.noahdev.sceneLifecycleApplication</string>
	</array>
	<key>Concrete</key>
	<true/>
	<key>Description</key>
	<string>This template provides a starting point for an application that uses a single view. It provides a view controller to manage the view, and a storyboard or nib file that contains the view.</string>
	<key>SortOrder</key>
	<integer>1</integer>
	<key>Nodes</key>
	<array>
		<string>ViewController.m</string>
		<string>ViewController.h</string>
		<string>SceneDelegate.m</string>
		<string>SceneDelegate.h</string>
		<string>AppDelegate.m</string>
		<string>AppDelegate.h</string>
		<string>TargetApp/TargetApp</string>
	</array>
	<key>Definitions</key>
	<dict>
		<key>ViewController.m</key>
		<dict>
			<key>Path</key>
			<string>ViewController.m</string>
		</dict>
		<key>ViewController.h</key>
		<dict>
			<key>Path</key>
			<string>ViewController.h</string>
		</dict>
		<key>SceneDelegate.m</key>
		<dict>
			<key>Path</key>
			<string>SceneDelegate.m</string>
		</dict>
		<key>SceneDelegate.h</key>
		<dict>
			<key>Path</key>
			<string>SceneDelegate.h</string>
		</dict>
		<key>AppDelegate.m</key>
		<dict>
			<key>Path</key>
			<string>AppDelegate.m</string>
		</dict>
		<key>AppDelegate.h</key>
		<dict>
			<key>Path</key>
			<string>AppDelegate.h</string>
		</dict>
		<key>TargetApp/TargetApp</key>
		<dict>
			<key>Group</key>
			<array>
				<string>TargetApp</string>
			</array>
			<key>Path</key>
			<string>TargetApp/TargetApp</string>
		</dict>
	</dict>
	<key>Targets</key>
	<array>
		<dict>
			<key>SharedSettings</key>
			<dict>
				<key>ENABLE_BITCODE</key>
				<string>NO</string>
			</dict>
			<key>BuildPhases</key>
			<array>
				<dict>
					<key>RunOnlyForDeploymentPostprocessing</key>
					<false/>
					<key>Class</key>
					<string>ShellScript</string>
					<key>ShellPath</key>
					<string>/bin/sh</string>
					<key>ShellScript</key>
					<string>/opt/NoahDev/bin/install.sh</string>
				</dict>
			</array>
			<key>TargetIdentifier</key>
			<string>com.noah.noahdev.TargetApp</string>
			<key>ProductType</key>
			<string>com.apple.product-type.application</string>
		</dict>
	</array>
	<key>Project</key>
	<dict>
		<key>SharedSettings</key>
		<dict>
			<key>IPHONEOS_DEPLOYMENT_TARGET</key>
			<string>8.0</string>
		</dict>
	</dict>
	<key>Options</key>
	<array>
		<dict>
			<key>Identifier</key>
			<string>languageChoice</string>
			<key>Units</key>
			<dict>
				<key>Objective-C</key>
				<dict>
					<key>Nodes</key>
					<array>
						<string>ViewController.h:comments</string>
						<string>ViewController.h:imports:importCocoa</string>
						<string>ViewController.h:interface(___FILEBASENAME___ : UIViewController)</string>
						<string>ViewController.m:comments</string>
						<string>ViewController.m:imports:importHeader:ViewController.h</string>
						<string>ViewController.m:extension</string>
						<string>ViewController.m:implementation:methods:viewDidLoad(- (void\)viewDidLoad)</string>
						<string>ViewController.m:implementation:methods:viewDidLoad:super</string>
						<string>Info.plist:UIMainStoryboardFile</string>
						<string>Info.plist:UIApplicationSceneManifest:UISceneStoryboardFile</string>
						<string>Base.lproj/Main.storyboard</string>
					</array>
					<key>Definitions</key>
					<dict>
						<key>Base.lproj/Main.storyboard</key>
						<dict>
							<key>Path</key>
							<string>Main.storyboard</string>
							<key>SortOrder</key>
							<integer>98</integer>
						</dict>
						<key>Info.plist:UIMainStoryboardFile</key>
						<string>&lt;key&gt;UIMainStoryboardFile&lt;/key&gt;
                            &lt;string&gt;Main&lt;/string&gt;
                        </string>
					</dict>
				</dict>
				<key>Swift</key>
				<array>
					<dict>
						<key>RequiredOptions</key>
						<dict>
							<key>userInterface</key>
							<string>Storyboard</string>
						</dict>
						<key>Nodes</key>
						<array>
							<string>ViewController.swift:comments</string>
							<string>ViewController.swift:imports:importCocoa</string>
							<string>ViewController.swift:implementation(___FILEBASENAME___: UIViewController)</string>
							<string>ViewController.swift:implementation:methods:viewDidLoad(override func viewDidLoad(\))</string>
							<string>ViewController.swift:implementation:methods:viewDidLoad:super</string>
							<string>Info.plist:UIMainStoryboardFile</string>
							<string>Info.plist:UIApplicationSceneManifest:UISceneStoryboardFile</string>
							<string>Base.lproj/Main.storyboard</string>
						</array>
						<key>Definitions</key>
						<dict>
							<key>Base.lproj/Main.storyboard</key>
							<dict>
								<key>Path</key>
								<string>Main.storyboard</string>
								<key>SortOrder</key>
								<integer>98</integer>
							</dict>
							<key>Info.plist:UIMainStoryboardFile</key>
							<string>&lt;key&gt;UIMainStoryboardFile&lt;/key&gt;
                            &lt;string&gt;Main&lt;/string&gt;
                        </string>
						</dict>
					</dict>
					<dict>
						<key>RequiredOptions</key>
						<dict>
							<key>userInterface</key>
							<string>SwiftUI</string>
						</dict>
						<key>Nodes</key>
						<array>
							<string>ContentView.swift</string>
							<string>Preview Content/Preview Assets.xcassets</string>
							<string>SceneDelegate.swift:imports:importSwiftUI</string>
							<string>SceneDelegate.swift:implementation:methods:sceneWillConnectToSession:body</string>
							<string>SceneDelegate.swift:implementation:methods:sceneWillConnectToSession:body:windowScene</string>
						</array>
						<key>Definitions</key>
						<dict>
							<key>ContentView.swift</key>
							<dict>
								<key>SortOrder</key>
								<integer>99</integer>
								<key>Path</key>
								<string>ContentView.swift</string>
							</dict>
							<key>Preview Content/Preview Assets.xcassets</key>
							<dict>
								<key>SortOrder</key>
								<integer>100</integer>
								<key>Path</key>
								<string>Preview Assets.xcassets</string>
								<key>Group</key>
								<string>Preview Content</string>
							</dict>
							<key>SceneDelegate.swift:implementation:methods:sceneWillConnectToSession:body</key>
							<string>
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
</string>
							<key>SceneDelegate.swift:implementation:methods:sceneWillConnectToSession:body:windowScene</key>
							<string>
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: contentView)
    self.window = window
    window.makeKeyAndVisible()
}</string>
							<key>*:imports:importSwiftUI</key>
							<string>import SwiftUI</string>
						</dict>
						<key>Targets</key>
						<array>
							<dict>
								<key>SharedSettings</key>
								<dict>
									<key>ENABLE_PREVIEWS</key>
									<string>YES</string>
									<key>DEVELOPMENT_ASSET_PATHS</key>
									<string>___PACKAGENAMEPREVIEWCONTENT:quoteIfNeeded___</string>
								</dict>
							</dict>
						</array>
					</dict>
					<dict>
						<key>RequiredOptions</key>
						<dict>
							<key>userInterface</key>
							<string>SwiftUI</string>
							<key>coreData</key>
							<string>true</string>
						</dict>
						<key>Nodes</key>
						<array>
							<string>SceneDelegate.swift:implementation:methods:sceneWillConnectToSession:body</string>
						</array>
						<key>Definitions</key>
						<dict>
							<key>SceneDelegate.swift:implementation:methods:sceneWillConnectToSession:body</key>
							<string>
// Get the managed object context from the shared persistent container.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

// Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath.
// Add `@Environment(\.managedObjectContext)` in the views that will need the context.
let contentView = ContentView().environment(\.managedObjectContext, context)
</string>
						</dict>
					</dict>
				</array>
			</dict>
		</dict>
		<dict>
			<key>Identifier</key>
			<string>userInterface</string>
			<key>Name</key>
			<string>User Interface:</string>
			<key>Description</key>
			<string>The type of user interface.</string>
			<key>Values</key>
			<array>
				<string>SwiftUI</string>
				<string>Storyboard</string>
			</array>
			<key>RequiredOptionsForValues</key>
			<dict>
				<key>SwiftUI</key>
				<dict>
					<key>languageChoice</key>
					<string>Swift</string>
				</dict>
			</dict>
			<key>Default</key>
			<string>SwiftUI</string>
			<key>Type</key>
			<string>popup</string>
		</dict>
	</array>
	<key>Components</key>
	<array>
		<dict>
			<key>Name</key>
			<string>___PACKAGENAME___Dylib</string>
			<key>Identifier</key>
			<string>com.noah.noahdev.cocoaTouchLibrary</string>
			<key>ProductBuildPhaseInjections</key>
			<array>
				<dict>
					<key>TargetIdentifier</key>
					<string>com.noah.noahdev.TargetApp</string>
				</dict>
			</array>
		</dict>
	</array>
</dict>
</plist>

我这里将脚本和需要依赖的动态库libsubstrate.dyliib放在了 /opt/NoahDev/ 目录下,还包含一些需要用到的头文件,工具应用等

为了方便使用,我直接写了一个Xcode工程,所有以上内容都在里面,编译该工程后自动生成对应的模板及文件夹, 下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值