Recently, while practicing Ruby, I wrote a small script to scan unused images in a project.
The principle is relatively simple. First, find the folder *.xcassets in the project where the image resources are stored, get the name of the image, and then go through the project to find the files we care about according to the name. For example, in iOS, the OC code is written in the *.h,*.m,*.mm file, and the swift code is written in the *.swift file. Then compare whether the following method is used by the regular.
OC call:
[UIImage imageNamed:@"xxx"]
Copy the code
Swift call:
UIImage(named: "xxx")
Copy the code
When using the script, open the terminal directly to run the script (remember to download log_color.rb file at the same time, and put in the same directory) :
ruby image_use_check.rb /Users/zl/Desktop/jinfeng/project/MY_SDK/FFText
Copy the code
Run the image_use_check.rb script with the Ruby interpreter and pass in a parameter, which is the path of a project. If you’re familiar with Ruby, please ignore it.
The running results are as follows:
You can see that there are three images that are not used: PJ-1, PJ-2, and PJ-3. Let’s just take a random image and look it up in the project,
OK, you can see that this image is not used.
Here directly paste the source code for your reference:
require_relative './log_color'
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
inputs = ARGV
# Target search path
search_path = ' '
if inputs.count > 0
search_path = inputs.first
else
search_path = Dir.pwd
end
# Target search path
Target_search_path = search_path
# These directories do not need searching
Except_dirs = ['Pods'.'. '.'.. '.'.git'.'.DS_Store'.'xcuserdata'.'xcshareddata'.'fastlane'.'Fastlane']
Target image folder name suffix
Target_image_dir_extname = '.xcassets'
The image name used in the # project is actually the name of the imageset folder
Target_useimage_dir_extname = '.imageset'
# identifies the image suffix type
Image_extnames = ['.png'.'.jpg'.'webp'.'.jpeg']
# Search for file suffix
Search_code_file_extnames = ['.h'.'.m'.'.mm'.'.swift']
class ImageDetector
def initialize(path)
@filePath = path
@imageName = File.basename(path, Target_useimage_dir_extname)
@match = false
end
def image_use?
@match
end
def image_name
@imageName
end
# Check whether the target image is used throughout the project
def beginSearch(path=Target_search_path, &block)
foreachDir(path) do |entry, full_path|
if File.file? full_path
file_extname = File.extname(full_path)
if Search_code_file_extnames.include? (file_extname)
# puts "Start search file " + color_text(entry, Color.green) + " in path #{full_path}"
_match(full_path) {
@match = true
if not block.nil?
block.call @imageName, full_path
end
break
}
end
elsif File.directory? full_path
Filter out some folders here
if File.extname(full_path) == Target_image_dir_extname
next
end
beginSearch(full_path, &block)
else
puts 'Unknow entry ' + color_text(entry, Color.red) + " in path #{full_path}"
end
end
end
Whether the target image is referenced in the file at this path
def _match(path, &block)
if not File::readable? path
return
end
# Check whether it is a swift file
is_swift = File.extname(path) == '.swift'
# Match judgment
def check_image_oc(str)
reg = /UIImage[\s]*imageNamed:@"# {@imageName}"/
reg_png = /UIImage[\s]*imageNamed:@"# {@imageName}\.png"/
if not (str =~ reg).nil? or not (str =~ reg_png).nil?
# puts 'Match success ' + color_text(str, Color.red)
return true
end
return false
end
def check_image_swift(str)
reg = /UIImage\(named:[\s]*"# {@imageName}"[\s]*\)/
reg_png = /UIImage\(named:[\s]*"# {@imageName}.png"[\s]*\)/
if not (str =~ reg).nil? or not (str =~ reg_png).nil?
# puts 'Match success ' + color_text(str, Color.red)
return true
end
return false
end
text = File.read(path)
res = false
if is_swift == true
res = check_image_swift text
else
res = check_image_oc text
end
if res == true
if not block.nil?
block.call path
end
end
end
end
def foreachDir(path, &block)
Dir.foreach(path) do |entry|
ifFile.directory? (path)and Except_dirs.include? (entry)next
end
if not block.nil?
full_path = path.to_s + "/" + entry.to_s
block.call entry, full_path
end
end
end
def start_search(path)
foreachDir(path) do |entry, full_path|
if File.directory? full_path
if File.extname(full_path) == Target_image_dir_extname
puts "Find *.xcassets in path=#{full_path}"
_search_image_inxcassets(full_path)
else
start_search(full_path)
end
end
end
end
# start with *.xcassets and iterate through the image
def _search_image_inxcassets(path)
foreachDir(path) do |entry, full_path|
if File.directory? full_path
if File.extname(full_path) == Target_useimage_dir_extname
Find the image and see if it was used in the project
detector = ImageDetector.new(full_path)
detector.beginSearch { |image_name, match_file_path|
# When there is a callback, a match has been made
# puts "Match success image named " + color_text(image_name, Color.green) + " in " + color_text(match_file_path, Color.white)
}
if not detector.image_use?
puts "Image named " + color_text(detector.image_name, Color.red) + "The unused!"
end
else
_search_image_inxcassets full_path
end
end
end
end
puts "Begin search..."
start_search(Target_search_path)
puts "Search finished, check appeal images is really unused in project."
Copy the code