Skip to content

Commit 320b916

Browse files
author
Eric Miller
committed
Use a config file to initialize UBKit
1 parent 371bb27 commit 320b916

File tree

11 files changed

+185
-67
lines changed

11 files changed

+185
-67
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ xcuserdata/
1919
.DS_Store
2020
iOS/
2121
Unity/
22+
ubconfig.json
2223

2324
## Other
2425
*.moved-aside

Sources/UBKit/Files/Xcode/SpecFile.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ extension File {
1414
It is specifically indented and formatted in order
1515
to work once the data is written to the spec file.
1616
*/
17-
class func specFile(projectName: String, bundleIdentifier: String) -> Data? {
17+
class func specFile(projectName: String, bundleIdentifier: String, unityVersion: String) -> Data? {
1818
let file = """
1919
name: \(projectName)
2020
configs:
@@ -31,7 +31,7 @@ extension File {
3131
PRODUCT_BUNDLE_IDENTIFIER: \(bundleIdentifier)
3232
IOS_DEPLOYMENT_TARGET: 11.0
3333
IPHONEOS_DEPLOYMENT_TARGET: 11.0
34-
UNITY_RUNTIME_VERSION: 2017.1.1f1
34+
UNITY_RUNTIME_VERSION: \(unityVersion)
3535
UNITY_SCRIPTING_BACKEND: il2cpp
3636
UNITY_IOS_EXPORT_PATH: ${SRCROOT}/../Unity/\(projectName)/ios_build
3737
GCC_PREFIX_HEADER: $(UNITY_IOS_EXPORT_PATH)/Classes/Prefix.pch

Sources/UBKit/Models/Config.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// Config.swift
3+
// UBKit
4+
//
5+
// Created by Eric Miller on 10/15/17.
6+
//
7+
8+
import Foundation
9+
10+
struct Config {
11+
12+
struct Keys {
13+
static let projectName = "project_name"
14+
static let bundleID = "bundle_id"
15+
static let unityPath = "unity_path"
16+
static let unityVersion = "unity_version"
17+
static let unitySceneName = "unity_scene_name"
18+
}
19+
20+
let projectName: String
21+
let bundleID: String
22+
let unityPath: String
23+
let unityVersion: String
24+
let unitySceneName: String
25+
let relativeIOSBuildPath: String
26+
let relativeUnityClassesPath: String
27+
let relativeUnityLibrariesPath: String
28+
29+
init?(json: [String : String]) {
30+
guard let projectName = json[Keys.projectName],
31+
let bundleID = json[Keys.bundleID], !bundleID.isEmpty,
32+
let unityPath = json[Config.Keys.unityPath], !unityPath.isEmpty,
33+
let unityVersion = json[Config.Keys.unityVersion], !unityVersion.isEmpty,
34+
let sceneName = json[Config.Keys.unitySceneName] else {
35+
return nil
36+
}
37+
38+
if projectName.isEmpty {
39+
guard let folderName = FileManager.default.currentDirectoryPath.components(separatedBy: "/").last else {
40+
return nil
41+
}
42+
self.projectName = folderName
43+
} else {
44+
self.projectName = projectName
45+
}
46+
47+
if sceneName.isEmpty {
48+
self.unitySceneName = self.projectName
49+
} else {
50+
self.unitySceneName = sceneName
51+
}
52+
53+
self.bundleID = bundleID
54+
self.unityPath = unityPath
55+
self.unityVersion = unityVersion
56+
57+
self.relativeIOSBuildPath = self.projectName.appending("/ios_build/")
58+
self.relativeUnityClassesPath = self.projectName.appending("/ios_build/Classes/")
59+
self.relativeUnityLibrariesPath = self.projectName.appending("/ios_build/Libraries/")
60+
}
61+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// UBKitError.swift
3+
// UBKit
4+
//
5+
// Created by Eric Miller on 10/14/17.
6+
//
7+
8+
import Foundation
9+
10+
enum UBKitError: Error {
11+
case error(Error)
12+
case unableToCreateFile(String)
13+
case invalidFolder
14+
case invalidXcodeProject
15+
case missingGroup(String)
16+
case invalidUnityProject
17+
case unableToCreateXcodeProjectGroup
18+
case unableToSaveXcodeProject
19+
case waitTimedOut
20+
case shellCommand
21+
case invalidConfigFile
22+
}

Sources/UBKit/UBKit.swift

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
import Foundation
22

33
public final class UBKit {
4+
45
private let arguments: [String]
5-
private let kitManager: UBKitManager
6+
private var kitManager: UBKitManager!
7+
8+
private let fileManager = FileManager.default
69

710
public init(arguments: [String] = CommandLine.arguments) {
811
self.arguments = arguments
9-
guard arguments.count == 3 else {
10-
print("FAILURE: Invalid number of arguments.")
11-
exit(1)
12-
}
13-
let projectName = arguments[1]
14-
let iOSBundleIdentifier = arguments[2]
15-
kitManager = UBKitManager(projectName: projectName, bundleIdentifier: iOSBundleIdentifier)
1612
}
1713

1814
public func run(_ completion: @escaping ((Error?) -> Void)) {
15+
let workingPath = fileManager.currentDirectoryPath
16+
do {
17+
if let fileData = fileManager.contents(atPath: workingPath.appending("/ubconfig.json")) {
18+
if let configJSON = try JSONSerialization.jsonObject(with: fileData, options: .allowFragments) as? [String : String] {
19+
guard let config = Config(json: configJSON) else {
20+
completion(UBKitError.invalidConfigFile)
21+
return
22+
}
23+
kitManager = UBKitManager(config: config)
24+
}
25+
26+
}
27+
} catch {
28+
completion(UBKitError.invalidFolder)
29+
}
30+
1931
let taskResult = kitManager.performTasks()
2032
guard taskResult == .success else {
2133
completion(taskResult.error)

Sources/UBKit/UBKitManager.swift

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,23 @@ import Foundation
1010

1111
class UBKitManager {
1212

13-
private let projectName: String
14-
private let bundleIdentifier: String
13+
private let config: Config
1514
private let xcodeProjectYMLFileName: String
1615
private let workingFolderPath: String
1716
private let workingiOSFolderPath: String
1817
private let workingUnityFolderPath: String
1918

2019
private let fileManager = FileManager.default
2120

22-
init(projectName: String, bundleIdentifier: String) {
23-
self.projectName = projectName
24-
self.bundleIdentifier = bundleIdentifier
21+
init(config: Config) {
22+
self.config = config
2523

2624
self.workingFolderPath = fileManager.currentDirectoryPath.appending("/")
2725
self.workingiOSFolderPath = workingFolderPath.appending("iOS/")
2826
self.workingUnityFolderPath = workingFolderPath.appending("Unity/")
2927
self.xcodeProjectYMLFileName = "project.yml"
3028
}
3129

32-
/**
33-
Performs the following tasks
34-
- Generate the iOS project's YAML file
35-
- Generate the iOS project's source folders/files
36-
- Gerenate the iOS project's Unity bridging folders/files
37-
- Create the iOS Xcode project
38-
39-
- Create the Unity project
40-
- Generate the project refresh script
41-
*/
4230
func performTasks() -> Result {
4331
print("\n----------")
4432
print("Creating iOS Project")
@@ -76,35 +64,39 @@ class UBKitManager {
7664
}
7765

7866
func createiOSProject() -> Result {
79-
let xcodeProject = XcodeProject(projectName: projectName, bundleIdentifier: bundleIdentifier, workingPath: workingiOSFolderPath)
67+
let xcodeProject = XcodeProject(
68+
projectName: config.projectName,
69+
bundleIdentifier: config.bundleID,
70+
workingPath: workingiOSFolderPath,
71+
unityVersion: config.unityVersion
72+
)
8073
return xcodeProject.create()
8174
}
8275

8376
func createUnityProject() -> Result {
84-
let unityProject = UnityProject(projectName: projectName, workingPath: workingUnityFolderPath)
77+
let unityProject = UnityProject(
78+
projectName: config.projectName,
79+
workingPath: workingUnityFolderPath,
80+
unityAppPath: config.unityPath
81+
)
8582
return unityProject.create()
8683
}
8784

8885
func refreshProjects() -> Result {
89-
let refreshser = ProjectRefresher(projectName: projectName, workingPath: workingFolderPath)
86+
let refreshser = ProjectRefresher(
87+
projectName: config.projectName,
88+
workingPath: workingFolderPath,
89+
sceneName: config.unitySceneName
90+
)
9091
return refreshser.refresh()
9192
}
9293

9394
func copyUnityFiles() -> Result {
94-
let fileCopier = FileCopier(projectName: projectName, workingPath: workingUnityFolderPath, xcodeProjectPath: workingiOSFolderPath)
95+
let fileCopier = FileCopier(
96+
config: config,
97+
workingPath: workingUnityFolderPath,
98+
xcodeProjectPath: workingiOSFolderPath
99+
)
95100
return fileCopier.copyFiles()
96101
}
97102
}
98-
99-
enum UBKitError: Error {
100-
case error(Error)
101-
case unableToCreateFile(String)
102-
case invalidFolder
103-
case invalidXcodeProject
104-
case missingGroup(String)
105-
case invalidUnityProject
106-
case unableToCreateXcodeProjectGroup
107-
case unableToSaveXcodeProject
108-
case waitTimedOut
109-
case shellCommand
110-
}

Sources/UBKit/Workers/FileCopier.swift

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class FileCopier {
1717
let buildFile: PBXBuildFile
1818
}
1919

20-
private let projectName: String
20+
private let config: Config
2121
private let workingPath: String
2222
private let xcodeProjectPath: String
2323
private let xcodeProjectFilePath: String
@@ -30,11 +30,11 @@ class FileCopier {
3030
private var classesGroup: PBXGroup?
3131
private var libsGroup: PBXGroup?
3232

33-
init(projectName: String, workingPath: String, xcodeProjectPath: String) {
34-
self.projectName = projectName
33+
init(config: Config, workingPath: String, xcodeProjectPath: String) {
34+
self.config = config
3535
self.workingPath = workingPath
3636
self.xcodeProjectPath = xcodeProjectPath
37-
self.xcodeProjectFilePath = String(format: "%@%@%@", xcodeProjectPath, projectName, ".xcodeproj")
37+
self.xcodeProjectFilePath = String(format: "%@%@%@", xcodeProjectPath, config.projectName, ".xcodeproj")
3838
}
3939

4040
func copyFiles() -> Result {
@@ -54,7 +54,7 @@ class FileCopier {
5454
}
5555

5656
print("Adding Unity files to Xcode project")
57-
let classesPath = workingPath.appending(projectName).appending("/ios_build/Classes/")
57+
let classesPath = workingPath.appending(config.relativeUnityClassesPath)
5858
guard let classesGroup = classesGroup else {
5959
return .failure(UBKitError.invalidUnityProject)
6060
}
@@ -63,7 +63,7 @@ class FileCopier {
6363
return addClassesFilesResult
6464
}
6565

66-
let librariesPath = workingPath.appending(projectName).appending("/ios_build/Libraries/")
66+
let librariesPath = workingPath.appending(config.relativeUnityLibrariesPath)
6767
guard let libsGroup = libsGroup else {
6868
return .failure(UBKitError.invalidUnityProject)
6969
}
@@ -90,8 +90,7 @@ private extension FileCopier {
9090
project = try XcodeProj(path: projectPath)
9191
return .success
9292
} catch {
93-
print("Failure: \(error.localizedDescription)")
94-
return .failure(UBKitError.invalidXcodeProject)
93+
return .failure(error)
9594
}
9695
}
9796

@@ -105,8 +104,8 @@ private extension FileCopier {
105104
return .failure(UBKitError.invalidXcodeProject)
106105
}
107106

108-
guard let targetGroup = project.pbxproj.groups.filter({ $0.path == projectName }).first else {
109-
return .failure(UBKitError.missingGroup(projectName))
107+
guard let targetGroup = project.pbxproj.groups.filter({ $0.path == config.projectName }).first else {
108+
return .failure(UBKitError.missingGroup(config.projectName))
110109
}
111110

112111
do {
@@ -142,14 +141,14 @@ private extension FileCopier {
142141
}
143142

144143
if let classesGroup = generateGroup("Classes", sourceTree: .absolute) {
145-
classesGroup.path = workingPath.appending(projectName).appending("/ios_build/Classes")
144+
classesGroup.path = workingPath.appending(config.relativeUnityClassesPath)
146145
project.pbxproj.addObject(classesGroup)
147146
self.classesGroup = classesGroup
148147
unityGroup.children.append(classesGroup.reference)
149148
}
150149

151150
if let librariesGroup = generateGroup("Libraries", sourceTree: .absolute) {
152-
librariesGroup.path = workingPath.appending(projectName).appending("/ios_build/Libraries")
151+
librariesGroup.path = workingPath.appending(config.relativeUnityLibrariesPath)
153152
project.pbxproj.addObject(librariesGroup)
154153
self.libsGroup = librariesGroup
155154
unityGroup.children.append(librariesGroup.reference)
@@ -177,10 +176,14 @@ private extension FileCopier {
177176
return .failure(UBKitError.invalidXcodeProject)
178177
}
179178

180-
let frameworksBuildPhases = project.pbxproj.frameworksBuildPhases
181-
guard frameworksBuildPhases.count == 1, let frameworksBuildPhase = frameworksBuildPhases.first else {
182-
return .failure(UBKitError.invalidXcodeProject)
179+
let frameworksBuildPhase = PBXFrameworksBuildPhase(reference: generateUUID(PBXFrameworksBuildPhase.self,
180+
"frameworks".appending(nameSalt)))
181+
if let mainTarget = project.pbxproj.nativeTargets.filter({ $0.name == config.projectName }).first,
182+
parentGroup.name == "Libraries" {
183+
mainTarget.buildPhases.append(frameworksBuildPhase.reference)
184+
print("Adding to main target")
183185
}
186+
project.pbxproj.addObject(frameworksBuildPhase)
184187

185188
@discardableResult
186189
func add(toPath: String, parentGroup: PBXGroup) -> Result {
@@ -363,7 +366,7 @@ private extension FileCopier {
363366
}
364367

365368
func generateSourceFile(path: Path, in group: PBXGroup, name: String) -> SourceFile? {
366-
let referencePath = Path(xcodeProjectPath.appending(projectName).appending("/").appending(projectName))
369+
let referencePath = Path(xcodeProjectPath.appending(config.projectName).appending("/").appending(config.projectName))
367370
guard let fileReference = getFileReference(path: path, inPath: referencePath, name: name) else {
368371
return nil
369372
}

Sources/UBKit/Workers/ProjectRefresher.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ class ProjectRefresher {
1717
private let refreshScriptName: String
1818
private let unitySceneName: String
1919

20-
init(projectName: String, workingPath: String) {
20+
init(projectName: String, workingPath: String, sceneName: String) {
2121
self.projectName = projectName
2222
self.workingPath = workingPath
2323

2424
self.refreshScriptName = "refreshProjects.swift"
25-
self.unitySceneName = "MainScene"
25+
self.unitySceneName = sceneName
2626
}
2727

2828
func refresh() -> Result {

Sources/UBKit/Workers/UnityProject.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ class UnityProject {
3333
private lazy var shell = Shell()
3434
private let unityAppPath: String
3535

36-
init(projectName: String, workingPath: String) {
36+
init(projectName: String, workingPath: String, unityAppPath: String) {
3737
self.projectName = projectName
3838
self.workingPath = workingPath
3939

40-
self.unityAppPath = "/Applications/Unity/Unity.app/Contents/MacOS/Unity"
40+
self.unityAppPath = unityAppPath
4141
}
4242

4343
func create() -> Result {

0 commit comments

Comments
 (0)