iOS項(xiàng)目中SDK的開發(fā)與調(diào)試

公司最近要開發(fā)一個(gè)SDK,不知如何下手,請教了一個(gè)有SDK開發(fā)經(jīng)驗(yàn)的同事剥槐,也在網(wǎng)上查了些資料,決定整理一下宪摧。整體上講就是在SVN上創(chuàng)建一個(gè)項(xiàng)目路徑才沧,再用Xcode創(chuàng)建一個(gè)項(xiàng)目工程迈喉,把項(xiàng)目工程上傳到SVN上就可以開發(fā)了剃根,這里只討論項(xiàng)目工程的創(chuàng)建盗飒。

一妇汗、創(chuàng)建一個(gè)workspace

1、在桌面上創(chuàng)建一個(gè)文件夾MyTestSDK(名字自己人昵浮)

2、打開Xcode,創(chuàng)建一個(gè)workspace,路徑放到文件夾MyTestSDK里面膝蜈,Xcode---File---New---Workspace

創(chuàng)建workspace

之后可以看到MyTestSDK文件夾里面多了一個(gè).xcworkspace文件

二锅移、創(chuàng)建SDK

1、打開MyTestSDK.xcworkspace文件饱搏,創(chuàng)建project

創(chuàng)建project

選擇Cocoa Touch Framework

創(chuàng)建framework

把framework添加到workspace里面

添加framework

添加之后的效果圖

效果

三非剃、創(chuàng)建Demo

1、打開MyTestSDK.xcworkspace文件推沸,創(chuàng)建project

創(chuàng)建project

2备绽、選擇Single View Application

選擇single view application

3、添加application到workspace

添加application

最終效果圖

效果圖

從上圖可以看出鬓催,上面是demo肺素,下面是sdk,怎么把這兩者關(guān)聯(lián)起來呢宇驾?倍靡??课舍?塌西??筝尾?捡需?

四、Demo的關(guān)聯(lián)以及SDK的開發(fā)調(diào)試

1忿等、把SDK打包成framework

這個(gè)步驟網(wǎng)上有很多種教程栖忠,最后可以手動(dòng)生成framework也可以用腳本生成framework,這里就以腳本生成framework為例贸街,其他方法有興趣的同學(xué)可以自己研究

參考:qingmang.me/articles/5162103427194116731/

這里創(chuàng)建一個(gè)MyView類庵寞,繼承于UIView,簡單的重寫了初始化方法薛匪,設(shè)置了顏色

創(chuàng)建一個(gè)類

設(shè)置Build Setting參數(shù)

設(shè)置參數(shù)

更改參數(shù)捐川,在Architectures下增加armv7s(iOS11上不支持armv7s,如果報(bào)錯(cuò)就不要添加),并選中逸尖。將Build Active Architecture only設(shè)置為NO

更改參數(shù)

設(shè)置Headers古沥,將要公開的頭文件拖到Public下瘸右,要隱藏的放到Private或Project下,隱藏的頭文件不能被引用

頭文件

然后需要在MyTestSDK.h(必須是公開的岩齿,否則無法引用)中將所有要公開的.h引入

引入頭文件

創(chuàng)建一個(gè)Aggregare

嵌入腳本太颤,選中剛剛創(chuàng)建的Aggregare,然后選中右側(cè)的Build Phases,點(diǎn)擊左邊的+號(hào),選擇New Run Script Phases

下面把這段腳本復(fù)制進(jìn)去(注意:腳本里面PROJECT_PATH_ARR中要設(shè)置自己工程路徑)

參考鏈接:iOS 打包FrameWork腳本 - 狂奔_蝸牛113 - 博客園

#!/bin/sh

#----------------------------------可以自定義的配置項(xiàng)--------------------------------------

#1.需要打包的工程路徑,全部是絕對(duì)路徑

#2.路徑必須到.xcodeproj

#3.如果該工程有多個(gè)Target,需要指定一個(gè)特定的Target來編譯盹沈,在路徑后面加(兩個(gè)下劃線)__Target名稱 例如:xxx/projectName.xcodeproj__TargetName

PROJECT_PATH_ARR=(

"/Users/xxx/Desktop/MyTestSDK/MyTestSDK/MyTestSDK.xcodeproj" \

)


#將PROJECT_PATH_ARR配置的地址【全部】Build出來的SDK所支持架構(gòu)龄章,設(shè)置0或者1

#0:支持真機(jī)和模擬器

#1:只支持真機(jī)

BUILD_SUPPORT_PLATFORM=0

#路徑相關(guān)配置

TMP_PATH="${HOME}/Desktop"? #編譯后的文件存放根路徑,此路徑默認(rèn)是桌面路徑乞封,可以自己指定對(duì)應(yīng)的路徑


#---------------------------------------------------------------------------------------------------------


#開始時(shí)間

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兩種選項(xiàng)

BUILD_TYPE="Release"


TMP_TARGET_NAME=""

TMP_FULL_PRODUCT_NAME=""



#創(chuàng)建文件路徑

#清除某個(gè)目錄里面的內(nèi)容做裙,如果有則清除內(nèi)容,沒有的直接創(chuàng)建該目錄

#參數(shù)1:目錄

clearDirAll(){

? ? ? ? if[ ! -d $1];

? ? then

? ? ? ? mkdir -p $1

? ? else

? ? ? ? #先刪除肃晚,再創(chuàng)建

? ? ? ? rm -rf $1

? ? ? ? mkdir -p $1

? ? fi

? ? return0

}


#創(chuàng)建Build根目錄

clearDirAll ${ROOT_BUILDPATH}

clearDirAll ${TMP_BUILDSETTING_DIR}

clearDirAll ${LOG_DIR}


#合并真機(jī)和模擬器

#參數(shù)1:當(dāng)前創(chuàng)建的Build目錄

mergeSDK(){

? ? #1.找到真機(jī)和模擬器路徑

? ? tmpIphonesPath="$1/${BUILD_TYPE}-iphoneos"

? ? tmpIphonesimulatorPath="$1/${BUILD_TYPE}-iphonesimulator"

? ? tmpSDKName=""

? ? #2.獲取當(dāng)前SDK名稱

? ? forfilein${tmpIphonesPath}/*

? ? do

? ? ? ? #拿到SDK文件名稱

? ? ? ? tmpName=`basename ${file}`

? ? ? ? if[[ $tmpName =~ $TMP_FULL_PRODUCT_NAME ]];then

? ? ? ? ? ? tmpSDKName=${tmpName}

? ? ? ? fi

? ? done


? ? #3.根據(jù)BUILD_SUPPORT_PLATFORM配置項(xiàng)判斷Build模擬器還是真機(jī)

? ? if[ $BUILD_SUPPORT_PLATFORM -eq0];then? #支持真機(jī)和模擬器


? ? ? ? #判斷當(dāng)前的SDK時(shí).a類型的還是.framework類型的,并且各自合并

? ? ? ? tmpAStr=".a"#當(dāng)前是.a形式的SDK

? ? ? ? tmpFStr=".framework" #當(dāng)前是.framework形式的SDK

? ? ? ? if[[ $tmpSDKName =~ $tmpFStr ]];then

? ? ? ? ? ? #獲取SDK名稱

? ? ? ? ? ? tmpFrameWorkName=${tmpSDKName%.*}

? ? ? ? ? ? #合并SDK

? ? ? ? ? ? #將真機(jī)模式下的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#只支持真機(jī)

? ? ? ? #如果只支持真機(jī)锚贱,就直接將真機(jī)目錄下的SDK拷貝到根目錄下就可以

? ? ? ? cp -r ${tmpIphonesPath}/${tmpSDKName} $1/${tmpSDKName}

? ? fi


? ? #4.將.h文件拷貝到.a文件的同級(jí)目錄下

? ? 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庫打包方法,接收兩個(gè)參數(shù)

#參數(shù)1:工程路徑,精確到xxx.xcodeproj

#參數(shù)2:TARGET名稱

buildLibrary(){

? ? if[ -n $1];then

? ? ? ? if[ -n $2];then

? ? ? ? ? ? #創(chuàng)建每個(gè).a的Build路徑

? ? ? ? ? ? buildDir="${ROOT_BUILDPATH}/$2"

? ? ? ? ? ? objRootPath="${TMP_OBJROOT}/$2"

? ? ? ? ? ? echo"--正在編譯 $2........."

? ? ? ? ? ? #創(chuàng)建目錄

? ? ? ? ? ? clearDirAll ${buildDir}


? ? ? ? ? ? logFile="${LOG_DIR}/$2-Build.log"

? ? ? ? ? ? #根據(jù)BUILD_SUPPORT_PLATFORM配置項(xiàng)判斷Build模擬器還是真機(jī)

? ? ? ? ? ? if[ $BUILD_SUPPORT_PLATFORM -eq0];then? #支持真機(jī)和模擬器


? ? ? ? ? ? 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真機(jī)---------------" >>${logFile}

? ? ? ? ? ? #開始Build真機(jī)

? ? ? ? ? ? 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#只支持真機(jī)


? ? ? ? ? ? echo"---------------開始Build真機(jī)---------------" >>${logFile}

? ? ? ? ? ? #開始Build真機(jī)

? ? ? ? ? ? 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.合并真機(jī)和模擬器

? ? ? ? ? ? mergeSDK ${buildDir};


? ? ? ? ? ? #4.移除工程根目錄下的build目錄

? ? ? ? ? ? tmpPath=$1

? ? ? ? ? ? projectPath=${tmpPath%/*}

? ? ? ? ? ? rm -rf"${projectPath}/build"

? ? ? ? ? ? rm -rf"${TMP_OBJROOT}"

? ? ? ? else

? ? ? ? ? ? echo"Target不能為空"

? ? ? ? fi

? ? else

? ? ? ? echo"工程路徑不能為空"

? ? fi

}


#導(dǎo)出BuildSetting文件并且找出TARGET_NAME和PRODUCT_NAME環(huán)境變量的值

#param1:工程路徑

#param2:TARGET名稱关串,如果沒有可以傳nil

readBuildSetting(){

? ? #0.清除全局變量的值

? ? TMP_TARGET_NAME=""

? ? TMP_FULL_PRODUCT_NAME=""

? ? #1.將工程工程對(duì)應(yīng)Target的BuildSetting文件導(dǎo)出到本地

? ? 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

? ? ? ? #執(zhí)行導(dǎo)出BuildSetting的文件

#? ? ? ? echo "命令:${cmdStr}"

? ? ? ? eval ${cmdStr}

? ? fi

? ? #2.解析導(dǎo)出的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.遍歷數(shù)組悍缠,根據(jù)路徑截取到相應(yīng)的工程路徑以及工程名

? ? 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.調(diào)用Build函數(shù)進(jìn)行Build

? ? ? ? buildLibrary ${projectPath} ${TMP_TARGET_NAME}

? ? done

}

echo "-----------------開始Build-----------------"

startBuild;

end_seconds=$(date +%s);

echo "-----------------Build完成? 耗時(shí):$((end_seconds-start_seconds))s-----------------"

#移除BuildSetting工作目錄

rm -rf "${TMP_BUILDSETTING_DIR}"

open ${ROOT_BUILDPATH}

如圖所示:

拷貝腳本

最后編譯,command + B飞蚓,編譯通過在桌面(不一定在桌面滤港,需要看腳本中自己設(shè)置的路徑)中找到framework,拷貝出來

編譯

2趴拧、Demo與SDK的關(guān)聯(lián)

把打包好的framework拖到demo里面

使用SDK溅漾,運(yùn)行demo

運(yùn)行的結(jié)果

這時(shí)候SDK跟Demo就關(guān)聯(lián)起來了,此時(shí)修改下面SDK中的代碼著榴,運(yùn)行demo就是修改后的效果添履,然后就可以愉快的在這個(gè)工程里面開發(fā)調(diào)試SDK了,如果我把MyView的顏色設(shè)置為yellow脑又,再去運(yùn)行demo暮胧,看一下效果

最后的最后,把這個(gè)工程上傳到SVN就可以愉快的開發(fā)了问麸。往衷。。以上是我個(gè)人的理解严卖,如有錯(cuò)誤席舍,請各位大牛批評(píng)指正,文中framework的打包方法參考網(wǎng)上資料哮笆,參考鏈接:qingmang.me/articles/5162103427194116731/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末来颤,一起剝皮案震驚了整個(gè)濱河市汰扭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌福铅,老刑警劉巖萝毛,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異滑黔,居然都是意外死亡珊泳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門拷沸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人薯演,你說我怎么就攤上這事撞芍。” “怎么了跨扮?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵序无,是天一觀的道長。 經(jīng)常有香客問我衡创,道長帝嗡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任璃氢,我火速辦了婚禮哟玷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘一也。我一直安慰自己巢寡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布椰苟。 她就那樣靜靜地躺著抑月,像睡著了一般。 火紅的嫁衣襯著肌膚如雪舆蝴。 梳的紋絲不亂的頭發(fā)上谦絮,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音洁仗,去河邊找鬼层皱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛京痢,可吹牛的內(nèi)容都是我干的奶甘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼祭椰,長吁一口氣:“原來是場噩夢啊……” “哼臭家!你這毒婦竟也來了疲陕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤钉赁,失蹤者是張志新(化名)和其女友劉穎蹄殃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體你踩,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诅岩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了带膜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吩谦。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖膝藕,靈堂內(nèi)的尸體忽然破棺而出式廷,到底是詐尸還是另有隱情,我是刑警寧澤芭挽,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布滑废,位于F島的核電站,受9級(jí)特大地震影響袜爪,放射性物質(zhì)發(fā)生泄漏蠕趁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一辛馆、第九天 我趴在偏房一處隱蔽的房頂上張望俺陋。 院中可真熱鬧,春花似錦怀各、人聲如沸倔韭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寿酌。三九已至,卻和暖如春硕蛹,著一層夾襖步出監(jiān)牢的瞬間醇疼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工法焰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秧荆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓埃仪,卻偏偏與公主長得像乙濒,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容