This article was first published on my personal blog: blog.shenyuanluo.com. Welcome to subscribe if you like.
There are plenty of tutorials online on how to integrate iOS native projects into Unity projects, which I won’t cover here. Here’s how to automate the process of Unity code updates to iOS projects.
In a regular Unity code update, you go through the following steps:
Unity
The code is compiled to generate the correspondingUnity_iOS
engineering- the
Unity_iOS
Project update code (generally:Libraries,Classes,DataUpdate file data for these three directories) to merge into nativeiOS
engineering - The native
iOS
Project add corresponding interface processing…
In fact, the second step of merging involves a lot of similar repetitive work. Each time, the code files are deleted and modified. Using BeyondCompare on a regular basis can meet current requirements. However, if you need to update Your Unity code frequently, there is no guarantee that every time you manually compare the code to the files that have been added to it, and it adds to the workload, so you decide to make a script to automate this process.
Unity code update process
Continue to refine the merging steps, which can be divided into the following:
- New Unity file
- Delete Unity files
- Modify Unity files
For these operation requirements, shell can meet these requirements. The general idea is as follows:
Go through Unity project files and iOS project files (mainly the Native subfolders under the Libraries, Data, folders and Classes directories). For new and modified files, you can directly cp them, and record the new files/folders. For deleted files, you can run the Unity project files and iOS project files (mainly the Native subfolders under the Classes directories). You can directly rm and record the deleted files or folders.
So I wrote a script like this:
Find new Unity files (shell)
#Recursively check for 'new' files
#Param1: indicates the source folder. Param2: indicates the destination folderFunction rec_check_add_file() {dir_list =$(ls $1)} for name in ${dir_list[*]} "$1" == "$source_dir" ] ; Then # top-level folder filter if [" $name "! = "Classes"] && [" $name "! = "Data"] && [" $name "! = "Libraries"]. then continue fi fi if [ "$1" == "$source_dir/Classes" ]; If ["$name"!= "Native"]; then continue fi fi if [ -f $1/$name ]; If [! -f $2/$name]; if [! -f $2/$name]; Add_file_array [${#add_file_array[@]}]=$2/$name $1/$name" cp $1/$name $2/$name # elif [-d $1/$name]; If [! -d $2/$name]; if [! -d $2/$name]; Add_foloder_array [${#add_foloder_array[@]}]=$2/$name [${#add_foloder_array[@]}] Rec_check_add_file $1/$name $2/$name $done}Copy the code
Find Unity delete file (shell)
#Recursively check for 'delete' files
#Param1: indicates the source folder. Param2: indicates the destination folder.Function rec_check_del_file() {dir_list =$(ls $1) # for name in ${dir_list[*]} # do if [-f $1/$name ]; If [! -f $2/$name]; if [! -f $2/$name]; Then # if the path '$2 / $name file does not exist del_file_array [${# del_file_array} [@]] = $2 / $name # records' delete' document# echo "Delete file:The $1/$name"Rm $1/$name [-d $1/$name]; If [! -d $2/$name]; if [! -d $2/$name]; Rec_check_del_file $1/$name = rec_check_del_file $1/$name = rec_check_del_file $1/$name = rec_check_del_file $1/$name = rec_check_del_file $1/$name = rec_check_del_file $1/$name = rec_check_del_file $1/$name = rec_check_del_file $1/$name = rec_check_del_file $1/$name $2/$name fi fi done }Copy the code
Now that the Unity project and iOS project physical files/folders are handled, it’s time to add/remove file/folder dependencies to the iOS project. At that time, I found that shell could not handle directly (mainly the processing of ***.xcodeProj file, I did not understand the logical relationship), then I found that some great people had gone ahead (I said that there was no mature solution for such a public demand), Xcodeproj: Xcodeproj: Xcodeproj: Xcodeproj: Xcodeproj: Xcodeproj: Xcodeproj: Xcodeproj: Xcodeproj
IOS project file dependencies added
With Xcodeproj, command line management of Xcode file dependencies is exceptionally convenient; However, the physical file relationship was handled in shell and the dependency relationship was handled in Ruby, two different scripting languages. Although both can be mixed with each other, but for me who is not very familiar with scripts, it is more difficult, simply write a set of physical file processing scripts in Ruby.
Find new Unity files (Ruby)
Recursively check for 'new' files
def rec_check_add_file(src_file_path, dest_file_path)
Dir.foreach(src_file_path) do |file_name|
# System 'hides' file filtering
if file_name == "." or file_name == ".." or file_name == ".DS_Store"
next
end
# resource folder filtering
if src_file_path == @source_dir_path # top-level folder filtering
iffile_name ! ="Classes" andfile_name ! ="Data" andfile_name ! ="Libraries"
next
end
end
# Classes/Native folder filtering
if src_file_path == @source_dir_path + "/Classes"
iffile_name ! ="Native"
next
end
end
if File.directory? (src_file_path + "/" + file_name) # if 'folder'
unless File.exist? (dest_file_path + "/" + file_name) # If the folder does not exist
@add_foloder_array.push(dest_file_path + "/" + file_name) # Record the 'new' folder
Dir.mkdir(dest_file_path + "/" + file_name) Create folder
end
# Recursive processing
rec_check_add_file(src_file_path + "/" + file_name, dest_file_path + "/" + file_name)
elsif File.file? (src_file_path + "/" + file_name) # if 'file'
unless File.exist? (dest_file_path + "/" + file_name) The file does not exist
@add_file_array.push(dest_file_path + "/" + file_name) # Record 'new' files
end
FileUtils.cp(src_file_path + "/" + file_name, dest_file_path + "/" + file_name) Copy to target path
end
end
end
Copy the code
Find Unity delete files (Ruby)
# Recursively check for 'delete' files
def rec_check_del_file(src_file_path, dest_file_path)
Dir.foreach(src_file_path) do |file_name|
# System 'hides' file filtering
if file_name == "." or file_name == ".." or file_name == ".DS_Store"
next
end
if File.directory? (src_file_path + "/" + file_name) # if 'folder'
if File.exist? (dest_file_path + "/" + file_name) If the folder exists
# Recursive processing
rec_check_del_file(src_file_path + "/" + file_name, dest_file_path + "/" + file_name)
else
rec_delete_file(src_file_path + "/" + file_name) # then recursively delete the files under the folder
end
elsif File.file? (src_file_path + "/" + file_name) # if 'file'
unless File.exist? (dest_file_path + "/" + file_name) The file does not exist
@del_file_array.push(src_file_path + "/" + file_name) # Record 'delete' file
File.delete(src_file_path + "/" + file_name) Delete the source file
end
end
end
end
Copy the code
Add Unity file dependencies (Ruby)
Add file dependencies
def add_reference(target, project, to_group, file_path, need_mrc)
if to_group andFile::exist? (file_path)iffile_path ! ="." andfile_path ! =".." andfile_path ! =".DS_Store"
pb_gen_file_path = file_path
if to_group.find_file_by_path(pb_gen_file_path)
puts pb_gen_file_path + " reference exist"
else
file_reference = to_group.new_reference(pb_gen_file_path)
if need_mrc and file_path.include? ("pbobjc.m")
target.add_file_references([file_reference],'-fno-objc-arc')
else
target.add_file_references([file_reference])
end
end
end
project.save
end
end
Copy the code
Remove Unity file dependencies (Ruby)
# Remove file dependencies
def rmv_reference(target, project, from_group, file_path)
if from_group and file_path
from_group.files.each do |file_ref|
if file_ref.real_path.to_s == file_path
file_ref.remove_from_project
target.source_build_phase.remove_file_reference(file_ref)
target.resources_build_phase.remove_file_reference(file_ref)
target.headers_build_phase.remove_file_reference(file_ref)
break
end
end
project.save
end
end
Copy the code
Unity code update automation is now complete!
I found that Ruby is much faster than shell in processing physical files. Shell takes 4-5 seconds to process the same engineering code file, while Ruby only takes 1-2 seconds. I remember shell commands being fast, but how come Ruby is faster than shell? If you know the big guy, but also hope to inform, thanks!
supplement
To add/remove file dependencies, you need to install the Ruby library Xcodeproj. If not, you need to install it
sudo gem install xcodeproj
Full script
The Ruby script file can be downloaded here
reference
- Lazy bonus: Modify Xcode projects with scripts
- Add files to the Xcode project using code
- Ruby operation project. Xcodeproj