vb 如何检测打印机是否联机_如何检测 iOS 应用程序是否使用 Swift?

c975d65acfb23d7e7cf90a902a3a53ce.png

作者 | Timac 
来源 | https://blog.timac.org

关于 iOS 13.1 中对 Swift 的使用,可参考 Apple 在 iOS 13.1 中使用 Swift 开发的应用程序

朴素的方法是检查应用程序是否在其 Frameworks 文件夹中包含 Swift 库:libswiftCore.dyliblibswiftFoundation.dylib 等。

以下是 macOS 10.12.1 中的 MRT.app 的 Frameworks 文件夹的内容 /System/Library/CoreServices/MRT.app/Contents/Frameworks/

b1cf1343f6f259087bdd9151517371d4.png

但是,这不是一个好方法,因为 iOS 和 macOS 在 /System/Library/PrivateFrameworks/Swift/ 中包含 Swift 库的私有副本。iOS 和 macOS 中的多个应用程序直接链接到这些系统库。

以下是 macOS 10.12.1 中的 PIPAgent.app 的 Frameworks 文件夹的内容 /System/Library/CoreServices/PIPAgent.app/Contents/Frameworks/

ccabee79f64de81bc933f147daba9d94.png

更好的方法是检查二进制文件是否链接到 Swift 库。可以通过命令行工具 otool 中使用 -L 选项轻松完成此操作:

-L 显示目标文件使用的共享库的名称和版本号,以及如果文件是共享库,则显示共享库 ID。

在 PIPAgent 应用程序上运行此命令时:

otool -L /System/Library/CoreServices/PIPAgent.app/Contents/MacOS/PIPAgent | grep swift

您将获得以下输出:

/System/Library/PrivateFrameworks/Swift/libswiftAppKit.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftCore.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftCoreData.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftCoreGraphics.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftCoreImage.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftDarwin.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftDispatch.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftFoundation.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftIOKit.dylib (compatibility version 1.0.0, current version 800.8.18)
/System/Library/PrivateFrameworks/Swift/libswiftObjectiveC.dylib (compatibility version 1.0.0, current version 800.8.18)

建立一个脚本

使用 otool 命令行工具,可以很容易地编写一个 bash 函数来判断文件是否是链接到 Swift 库的二进制文件:

#------------------------------------------------------------------------
# Function to check if a file (passed as argument $1) is using Swift
# It returns the number of occurrences of the string 'swift'
# from the output of otool
#------------------------------------------------------------------------
isFileUsingSwift ()
{
otool -L $1 2>/dev/null | grep -o swift | wc -l
}

如果文件是链接到 Swift 库的二进制文件,则 processFile bash 函数将文件作为参数并打印其路径:

#------------------------------------------------------------------------
# Function to process a file (passed as argument $1).
# It calls the function isFileUsingSwift() to determine
# if this is a binary using Swift and in this case
# print the path of this file.
#------------------------------------------------------------------------
processFile ()
{
isFileUsingSwift=$( isFileUsingSwift $1 )
if [ ${isFileUsingSwift} != 0 ]
then
# We found a binary using Swift
echo " $1"
fi
}

现在遍历文件夹的所有文件仅需一行:

find ${PATH_TO_CHECK} -type f -exec bash -c 'processFile "$0"' {} \;

最终脚本

下面是一个完整的 bash 脚本,该脚本循环遍历一个文件夹的所有文件,并显示找到的所有使用 Swift 的二进制文件的路径。

#!/bin/bash
#---------------------------------------------------------------------
# Bash script that loops through all the files of a folder and
# print the paths of all the binaries found that use Swift
# Created by Alexandre Colucci on 01.11.2016
# https://blog.timac.org/2016/1101-apples-use-of-swift-in-ios-10-1-and-macos-10-12
#---------------------------------------------------------------------


#---------------------------------------------------------------------
# Force expand a wildcard pattern into the list of matching pathnames
#---------------------------------------------------------------------
shopt -s nullglob

#---------------------------------------------------------------------
# Function to print the usage
#---------------------------------------------------------------------
printUsage ()
{
echo "Usage: detectSwift.sh PATH"
echo "PATH: Folder to search for binaries using Swift"
echo ""
echo "Examples:"
echo " detectSwift.sh /System/Library"
echo " detectSwift.sh /System"
echo " detectSwift.sh /"
echo ""
echo "Note: run as root in order to avoid permission issues."
echo ""
}

#---------------------------------------------------------------------
# Function to check if a file (passed as argument $1) is using Swift
# It returns the number of occurrences of the string 'swift'
# from the output of otool
#---------------------------------------------------------------------
isFileUsingSwift ()
{
otool -L $1 2>/dev/null | grep -o swift | wc -l
}

#---------------------------------------------------------------------
# Function to process a file (passed as argument $1).
# It calls the function isFileUsingSwift() to determine
# if this is a binary using Swift and in this case
# print the path of this file.
#---------------------------------------------------------------------
processFile ()
{
isFileUsingSwift=$( isFileUsingSwift $1 )
if [ ${isFileUsingSwift} != 0 ]
then
# We found a binary using Swift
echo " $1"
fi
}

#---------------------------------------------------------------------
# Check if the script was called with the expected usage
#---------------------------------------------------------------------
PARAMETER_NUMBER=$#
PARAMETER_REQUIRED=1
if [ $PARAMETER_NUMBER != $PARAMETER_REQUIRED ];
then
printUsage
exit 1
fi


#---------------------------------------------------------------------
# Get the folder path
#---------------------------------------------------------------------
PATH_TO_CHECK=$1

echo ""
echo "Start time:"
date
echo ""
echo "Apps using Swift in ${PATH_TO_CHECK}"


#---------------------------------------------------------------------
# Export the functions so that the subshell inherits them
#---------------------------------------------------------------------
export -f isFileUsingSwift
export -f processFile

#---------------------------------------------------------------------
# Find all the regular files in all subdirectories
# and call for each the function processFile()
#---------------------------------------------------------------------

find ${PATH_TO_CHECK} -type f -exec bash -c 'processFile "$0"' {} \;


#---------------------------------------------------------------------
# Finalizing
#---------------------------------------------------------------------
echo ""
echo "Completed at:"
date
echo ""

运行脚本

该脚本确实很慢:对于每个常规文件,它将创建一个 subshell,分别调用otoolgrep 和 wc

在 iOS 10.1 文件系统上运行此脚本大约需要 30 分钟。

对于 macOS 10.12.1,在 / 路径上运行脚本需要花费数十个小时。我建议仅在 /System/Applications 和 /usr 上运行此脚本。并行处理这 3 个文件夹大约需要 2 个小时。


推荐阅读
• Xcode 11 的那些新东西 • 今年的 Swift,有哪些新的东西呢? • React Native 0.61 发布,带来了“快速刷新”功能 • iOS 启动时间与Dyld3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值