公司最近要開發一個SDK,不知如何下手,請教了一個有SDK開發經驗的同事,也在網上查了些資料,決定整理一下。整體上講就是在SVN上創建一個項目路徑,再用Xcode創建一個項目工程,把項目工程上傳到SVN上就可以開發了,這里只討論項目工程的創建。
一、創建一個workspace
1、在桌面上創建一個文件夾MyTestSDK(名字自己取)
2、打開Xcode,創建一個workspace,路徑放到文件夾MyTestSDK里面,Xcode---File---New---Workspace
之后可以看到MyTestSDK文件夾里面多了一個.xcworkspace文件
二、創建SDK
1、打開MyTestSDK.xcworkspace文件,創建project
選擇Cocoa Touch Framework
把framework添加到workspace里面
添加之后的效果圖
三、創建Demo
1、打開MyTestSDK.xcworkspace文件,創建project
2、選擇Single View Application
3、添加application到workspace
最終效果圖
從上圖可以看出,上面是demo,下面是sdk,怎么把這兩者關聯起來呢????????
四、Demo的關聯以及SDK的開發調試
1、把SDK打包成framework
這個步驟網上有很多種教程,最后可以手動生成framework也可以用腳本生成framework,這里就以腳本生成framework為例,其他方法有興趣的同學可以自己研究
參考:qingmang.me/articles/5162103427194116731/
這里創建一個MyView類,繼承于UIView,簡單的重寫了初始化方法,設置了顏色
設置Build Setting參數
更改參數,在Architectures下增加armv7s(iOS11上不支持armv7s,如果報錯就不要添加),并選中。將Build Active Architecture only設置為NO
設置Headers,將要公開的頭文件拖到Public下,要隱藏的放到Private或Project下,隱藏的頭文件不能被引用
然后需要在MyTestSDK.h(必須是公開的,否則無法引用)中將所有要公開的.h引入
創建一個Aggregare
嵌入腳本,選中剛剛創建的Aggregare,然后選中右側的Build Phases,點擊左邊的+號,選擇New Run Script Phases
下面把這段腳本復制進去(注意:腳本里面PROJECT_PATH_ARR中要設置自己工程路徑)
參考鏈接:iOS 打包FrameWork腳本 - 狂奔_蝸牛113 - 博客園
#!/bin/sh
#----------------------------------可以自定義的配置項--------------------------------------
#1.需要打包的工程路徑,全部是絕對路徑
#2.路徑必須到.xcodeproj
#3.如果該工程有多個Target,需要指定一個特定的Target來編譯,在路徑后面加(兩個下劃線)__Target名稱 例如:xxx/projectName.xcodeproj__TargetName
PROJECT_PATH_ARR=(
"/Users/xxx/Desktop/MyTestSDK/MyTestSDK/MyTestSDK.xcodeproj" \
)
#將PROJECT_PATH_ARR配置的地址【全部】Build出來的SDK所支持架構,設置0或者1
#0:支持真機和模擬器
#1:只支持真機
BUILD_SUPPORT_PLATFORM=0
#路徑相關配置
TMP_PATH="${HOME}/Desktop"? #編譯后的文件存放根路徑,此路徑默認是桌面路徑,可以自己指定對應的路徑
#---------------------------------------------------------------------------------------------------------
#開始時間
start_seconds=$(date +%s);
CURRENT_DATE=`date +%Y-%m-%d_%H-%M-%S`
ROOT_BUILDPATH="${TMP_PATH}/PbLib${CURRENT_DATE}"
TMP_SYMROOT="${ROOT_BUILDPATH}"
TMP_OBJROOT="${TMP_SYMROOT}/TMP_build"
LOG_DIR="${ROOT_BUILDPATH}/Build_Log"
TMP_BUILDSETTING_DIR="${ROOT_BUILDPATH}/TMP_BuildSetting"
#build類型? 有elease和dDebug兩種選項
BUILD_TYPE="Release"
TMP_TARGET_NAME=""
TMP_FULL_PRODUCT_NAME=""
#創建文件路徑
#清除某個目錄里面的內容,如果有則清除內容,沒有的直接創建該目錄
#參數1:目錄
clearDirAll(){
? ? ? ? if[ ! -d $1];
? ? then
? ? ? ? mkdir -p $1
? ? else
? ? ? ? #先刪除,再創建
? ? ? ? rm -rf $1
? ? ? ? mkdir -p $1
? ? fi
? ? return0
}
#創建Build根目錄
clearDirAll ${ROOT_BUILDPATH}
clearDirAll ${TMP_BUILDSETTING_DIR}
clearDirAll ${LOG_DIR}
#合并真機和模擬器
#參數1:當前創建的Build目錄
mergeSDK(){
? ? #1.找到真機和模擬器路徑
? ? tmpIphonesPath="$1/${BUILD_TYPE}-iphoneos"
? ? tmpIphonesimulatorPath="$1/${BUILD_TYPE}-iphonesimulator"
? ? tmpSDKName=""
? ? #2.獲取當前SDK名稱
? ? forfilein${tmpIphonesPath}/*
? ? do
? ? ? ? #拿到SDK文件名稱
? ? ? ? tmpName=`basename ${file}`
? ? ? ? if[[ $tmpName =~ $TMP_FULL_PRODUCT_NAME ]];then
? ? ? ? ? ? tmpSDKName=${tmpName}
? ? ? ? fi
? ? done
? ? #3.根據BUILD_SUPPORT_PLATFORM配置項判斷Build模擬器還是真機
? ? if[ $BUILD_SUPPORT_PLATFORM -eq0];then? #支持真機和模擬器
? ? ? ? #判斷當前的SDK時.a類型的還是.framework類型的,并且各自合并
? ? ? ? tmpAStr=".a"#當前是.a形式的SDK
? ? ? ? tmpFStr=".framework" #當前是.framework形式的SDK
? ? ? ? if[[ $tmpSDKName =~ $tmpFStr ]];then
? ? ? ? ? ? #獲取SDK名稱
? ? ? ? ? ? tmpFrameWorkName=${tmpSDKName%.*}
? ? ? ? ? ? #合并SDK
? ? ? ? ? ? #將真機模式下的FrameWork拷貝一份到根目錄下
? ? ? ? ? ? cp -r ${tmpIphonesPath}/${tmpSDKName} $1/${tmpSDKName}
? ? ? ? ? ? lipo -create"${tmpIphonesPath}/${tmpSDKName}/${tmpFrameWorkName}" "${tmpIphonesimulatorPath}/${tmpSDKName}/${tmpFrameWorkName}" -output "$1/${tmpSDKName}/${tmpFrameWorkName}"
? ? ? ? elif[[ $tmpSDKName =~ $tmpAStr ]];then
? ? ? ? ? ? #合并SDK
? ? ? ? ? ? lipo -create"${tmpIphonesPath}/${tmpSDKName}" "${tmpIphonesimulatorPath}/${tmpSDKName}" -output "$1/${tmpSDKName}"
? ? ? ? fi
? ? elif[ $BUILD_SUPPORT_PLATFORM -eq1];then#只支持真機
? ? ? ? #如果只支持真機,就直接將真機目錄下的SDK拷貝到根目錄下就可以
? ? ? ? cp -r ${tmpIphonesPath}/${tmpSDKName} $1/${tmpSDKName}
? ? fi
? ? #4.將.h文件拷貝到.a文件的同級目錄下
? ? find $1-maxdepth1-type d -name"*.h"-exec rm -rf {} \;
? ? find ${tmpIphonesPath} -maxdepth1-type f -name"*.h"-exec mv -f {} $1\;
? ? #5.移除iphones目錄和iphonesimulator目錄
? ? rm -rf"${tmpIphonesPath}"
? ? rm -rf"${tmpIphonesimulatorPath}"
}
#.a庫打包方法,接收兩個參數
#參數1:工程路徑,精確到xxx.xcodeproj
#參數2:TARGET名稱
buildLibrary(){
? ? if[ -n $1];then
? ? ? ? if[ -n $2];then
? ? ? ? ? ? #創建每個.a的Build路徑
? ? ? ? ? ? buildDir="${ROOT_BUILDPATH}/$2"
? ? ? ? ? ? objRootPath="${TMP_OBJROOT}/$2"
? ? ? ? ? ? echo"--正在編譯 $2........."
? ? ? ? ? ? #創建目錄
? ? ? ? ? ? clearDirAll ${buildDir}
? ? ? ? ? ? logFile="${LOG_DIR}/$2-Build.log"
? ? ? ? ? ? #根據BUILD_SUPPORT_PLATFORM配置項判斷Build模擬器還是真機
? ? ? ? ? ? if[ $BUILD_SUPPORT_PLATFORM -eq0];then? #支持真機和模擬器
? ? ? ? ? ? echo"---------------開始Build模擬器---------------" >>${logFile}
? ? ? ? ? ? #開始Build模擬器
? ? ? ? ? ? xcodebuild? -configuration"${BUILD_TYPE}"ONLY_ACTIVE_ARCH=NO -project"$1"-target"$2"SYMROOT="${TMP_SYMROOT}"OBJROOT="${objRootPath}"BUILD_DIR="${buildDir}"-sdk iphonesimulator clean build >>${logFile}
? ? ? ? ? ? echo"---------------開始Build真機---------------" >>${logFile}
? ? ? ? ? ? #開始Build真機
? ? ? ? ? ? xcodebuild -configuration"${BUILD_TYPE}"ONLY_ACTIVE_ARCH=NO -project"$1"-target"$2"SYMROOT="${TMP_SYMROOT}"OBJROOT="${objRootPath}"BUILD_DIR="${buildDir}"-sdk iphoneos clean build >>${logFile}
? ? ? ? ? ? elif[ $BUILD_SUPPORT_PLATFORM -eq1];then#只支持真機
? ? ? ? ? ? echo"---------------開始Build真機---------------" >>${logFile}
? ? ? ? ? ? #開始Build真機
? ? ? ? ? ? xcodebuild -configuration"${BUILD_TYPE}"ONLY_ACTIVE_ARCH=NO -project"$1"-target"$2"SYMROOT="${TMP_SYMROOT}"OBJROOT="${objRootPath}"BUILD_DIR="${buildDir}"-sdk iphoneos clean build >>${logFile}
? ? ? ? ? ? fi
? ? ? ? ? ? #3.合并真機和模擬器
? ? ? ? ? ? mergeSDK ${buildDir};
? ? ? ? ? ? #4.移除工程根目錄下的build目錄
? ? ? ? ? ? tmpPath=$1
? ? ? ? ? ? projectPath=${tmpPath%/*}
? ? ? ? ? ? rm -rf"${projectPath}/build"
? ? ? ? ? ? rm -rf"${TMP_OBJROOT}"
? ? ? ? else
? ? ? ? ? ? echo"Target不能為空"
? ? ? ? fi
? ? else
? ? ? ? echo"工程路徑不能為空"
? ? fi
}
#導出BuildSetting文件并且找出TARGET_NAME和PRODUCT_NAME環境變量的值
#param1:工程路徑
#param2:TARGET名稱,如果沒有可以傳nil
readBuildSetting(){
? ? #0.清除全局變量的值
? ? TMP_TARGET_NAME=""
? ? TMP_FULL_PRODUCT_NAME=""
? ? #1.將工程工程對應Target的BuildSetting文件導出到本地
? ? BuildSettingFile="${TMP_BUILDSETTING_DIR}/tmp_buildSetting.txt"
? ? if[ -n"$1"];then
? ? ? ? cmdStr="xcodebuild -list -project $1 -showBuildSettings >${BuildSettingFile}"
? ? ? ? if[ -n"$2"];then
? ? ? ? ? ? cmdStr="xcodebuild -list -project $1 -target $2 -showBuildSettings >${BuildSettingFile} "
? ? ? ? fi
? ? ? ? #執行導出BuildSetting的文件
#? ? ? ? echo "命令:${cmdStr}"
? ? ? ? eval ${cmdStr}
? ? fi
? ? #2.解析導出的BuildSetting文件,找出其中的TARGET_NAME和PRODUCT_NAME,并賦值給TMP_TARGET_NAME,TMP_PRODUCT_NAME
? ? IFS='='
? ? whilereadk v
? ? do
? ? if[["$k"== *FULL_PRODUCT_NAME* ]];then
?? ? ? TMP_FULL_PRODUCT_NAME=$(echo $v | sed's/[[:space:]]//g')
? ? elif[["$k"== *TARGET_NAME* ]];then
?? ? ? TMP_TARGET_NAME=$(echo $v | sed's/[[:space:]]//g')
? ? fi
? ? done< ${BuildSettingFile}
#? ? echo "TMP_FULL_PRODUCT_NAME=${TMP_FULL_PRODUCT_NAME}? TMP_TARGET_NAME=${TMP_TARGET_NAME}"
? ? rm -rf"${BuildSettingFile}"
}
startBuild(){
? ? #1.遍歷數組,根據路徑截取到相應的工程路徑以及工程名
? ? forproPathin${PROJECT_PATH_ARR[*]}
? ? do
? ? ? ? #2.獲取工程路徑
? ? ? ? projectPath=${proPath}
? ? ? ? targetName=""
? ? ? ? #3.判斷工程路徑中是否包含__,如果包含了則說明指定了Target
? ? ? ? tmpStr="__"
? ? ? ? if[[ $proPath =~ $tmpStr ]]
? ? ? ? then
? ? ? ? ? ? projectPath=${proPath%__*}
? ? ? ? ? ? #取到需要的Target名稱
? ? ? ? ? ? targetName=${proPath#*__}
? ? ? ? fi
? ? ? ? #4.判斷targetName是否為空,如果為空則代表TargetName和工程名稱相同
#? ? ? ? if [ -z "${targetName}" ];then
#? ? ? ? ? ? xcodeproj=${projectPath##*/}
#? ? ? ? ? ? projectName=${xcodeproj%.*}
#? ? ? ? ? ? targetName=${projectName}
#? ? ? ? fi
? ? ? ? #5.讀取TARGET_NAME和PRODUCT_NAME
? ? ? ? readBuildSetting ${projectPath} ${targetName}
? ? ? ? #6.調用Build函數進行Build
? ? ? ? buildLibrary ${projectPath} ${TMP_TARGET_NAME}
? ? done
}
echo "-----------------開始Build-----------------"
startBuild;
end_seconds=$(date +%s);
echo "-----------------Build完成? 耗時:$((end_seconds-start_seconds))s-----------------"
#移除BuildSetting工作目錄
rm -rf "${TMP_BUILDSETTING_DIR}"
open ${ROOT_BUILDPATH}
如圖所示:
最后編譯,command + B,編譯通過在桌面(不一定在桌面,需要看腳本中自己設置的路徑)中找到framework,拷貝出來
2、Demo與SDK的關聯
把打包好的framework拖到demo里面
使用SDK,運行demo
運行的結果
這時候SDK跟Demo就關聯起來了,此時修改下面SDK中的代碼,運行demo就是修改后的效果,然后就可以愉快的在這個工程里面開發調試SDK了,如果我把MyView的顏色設置為yellow,再去運行demo,看一下效果
最后的最后,把這個工程上傳到SVN就可以愉快的開發了。。。以上是我個人的理解,如有錯誤,請各位大牛批評指正,文中framework的打包方法參考網上資料,參考鏈接:qingmang.me/articles/5162103427194116731/