這裏主要參考這個項目:iOS-nRF-Toolbox,它是Nordic公司開發的測試工程,包含一整套nRF設備的測試解決方案。git
項目是用Swift寫的,不過以前仍是有OC版本的,可是後來因爲一些**(不可描述的問題),才變成了如今的純Swift版本。對於使用Swift開發的人員,直接仿照Demo操做便可。若是你是用Swift開發的,那下面的內容你能夠不用看了。接下來我就講一下針對OC引用DFU升級的操做步驟和我遇到的問題。github
nRF-Toolbox項目包含BGM,HRM,HTM,DFU等多個模塊,咱們今天只關注其中的DFU升級模塊。打開項目,在對應的NORDFUViewController.swift
中咱們可以看到有三個引用庫 import UIKit
,import CoreBluetooth
,import iOSDFULibrary
,這裏的iOSDFULibrary就是DFU升級的庫,也是解決DFU升級最重要的組件。咱們只要把這個庫集成到咱們的項目中,就可以完成nRF設備的DFU升級了。swift
有兩種方案集成:ruby
第一種方案是做者推薦的,可是我試了好久,引入DFULibrary會出現頭文件找不到等一系列問題,無奈只能放棄,若是有人經過這種方式成功,還望告知。下面講的是經過第二種方案的集成。bash
第一步:導出iOSDFULibraryapp
這一步是最關鍵也是最容易出問題的,這個庫也是由Swift寫成的,咱們將這個庫clone到本地,而後選擇iOSDFULibrary進行編譯curl
最後生成兩個framework:工具
這時庫內的代碼已經變成了咱們熟悉的OC語言。理論上這個庫應該是沒問題的了,可是事實仍是有問題的,見issues#39。做者給出的解決方法是:oop
一、On your mac please install carthage (instructions)測試
二、Create a file named cartfile anywhere on your computer
三、add the following content to the file:
github "NordicSemiconductor/IOS-Pods-DFU-Library" ~> 2.1.2 github "marmelroy/Zip" ~> 0.6 複製代碼
一、Open a new terminal and cd to the directory where the file is
二、Enter the command carthage update --platform iOS
三、Carthage will now take care of building your frameworks, the produced .framework files will be found in a newly created directory called Carthage/Build/iOS,copy over iOSDFULibrary.framework and Zip.framework to your project and you are good to go.
carthage是一種和cocoapods類似的的類庫管理工具,若是不會使用的話能夠參照Demo,將framework文件導入到本身的項目。
第二步、導入framework Target->General
直接拖入項目默認只會導入到Linked Frameworks and Libraries
,咱們還須要在Embeded Binaries中引入。
第三步、使用iOSDFULibrary
//create a DFUFirmware object using a NSURL to a Distribution Packer(ZIP)
DFUFirmware *selectedFirmware = [[DFUFirmware alloc] initWithUrlToZipFile:url];// or
//Use the DFUServiceInitializer to initialize the DFU process.
DFUServiceInitiator *initiator = [[DFUServiceInitiator alloc] initWithCentralManager: centralManager target:selectedPeripheral];
[initiator withFirmware:selectedFirmware];
// Optional:
// initiator.forceDfu = YES/NO; // default NO
// initiator.packetReceiptNotificationParameter = N; // default is 12
initiator.logger = self; // - to get log info
initiator.delegate = self; // - to be informed about current state and errors
initiator.progressDelegate = self; // - to show progress bar
// initiator.peripheralSelector = ... // the default selector is used
DFUServiceController *controller = [initiator start];
複製代碼
庫中有三個代理方法DFUProgressDelegate
,DFUServiceDelegate
,LoggerDelegate
,它們的做用分別爲監視DFU升級進度,DFU升級及藍牙鏈接狀態,打印狀態日誌。
一、selectedFirmware返回nil
DFUFirmware *selectedFirmware = [[DFUFirmware alloc] initWithUrlToZipFile:url];
複製代碼
須要在General
的Embeded Binaries
選項卡里導入那Zip.framework
和iOSDFULibrary.framework
二、崩潰報錯
dyld: Library not loaded: @rpath/libswiftCore.dylibReferenced from: /private/var/containers/Bundle/Application/02516D79-BB30-4278-81B8-3F86BF2AE2A7/XingtelBLE.app/Frameworks/iOSDFULibrary.framework/iOSDFULibraryReason: image not found
複製代碼
須要改兩個地方
若是不起做用,將Runpath Search Paths的選項內容刪掉再從新添加一遍便可 三、 打包上架時報ERROR IT MS-90087等問題 問題描述:ERROR ITMS-90087: "Unsupported Architectures. The executable for ***.app/Frameworks/SDK.framework contains unsupported architectures '[x86_64, i386]'."
ERROR ITMS-90362: "Invalid Info.plist value. The value for the key 'MinimumOSVersion' in bundle ***.app/Frameworks/SDK.framework is invalid. The minimum value is 8.0"
ERROR ITMS-90209: "Invalid Segment Alignment. The app binary at '***.app/Frameworks/SDK.framework/SDK' does not have proper segment alignment. Try rebuilding the app with the latest Xcode version."
ERROR ITMS-90125: "The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's linker."
複製代碼
解決方法,添加Run Script Phase
Shell腳本內容填寫以下內容,再次編譯便可APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
複製代碼
這個是對應Swift版本用OC寫的完整項目,應該是OC中止維護以前的版本。會有一些bug。在將DFUFramework更新以後,我把它搬到了個人github上,有須要的同窗能夠下載研究:OC-nRFTool-box。
如下爲更新內容,時間:2017.12.26 收到不少關於沒法適配Xcode9.2的反饋,由於最近比較忙沒時間處理,很差意思啦,今天抽出時間來把代碼更新了一下。
一、dyld: Library not loaded: @rpath/libswiftCore.dylib Referenced from: /private/var/containers/Bundle/Application/02516D79-BB30-4278-81B8-3F86BF2AE2A7/XingtelBLE.app/Frameworks/iOSDFULibrary.framework/iOSDFULibrary Reason: image not found
二、DFUFirmware *selectedFirmware = [[DFUFirmware alloc] initWithUrlToZipFile:url]; 返回爲空或者崩潰問題
個人測試結果是更新iOSDFULibrary. framework和Zip.framework能夠解決以上問題。
由於這兩個庫都是經過Swift維護的,因此更新framework最好仍是要用適用Swift的方式,包括之後的更新也同樣。因此我推薦用Carthage更新這倆庫,下面是使用Carthage的簡單介紹,詳細的能夠看這裏Carthage的安裝和使用。 另外OC-nRFTool-box也已經更新,裏面的Framework能夠直接拿來用。
一、安裝brew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
複製代碼
二、brew更新
brew update
複製代碼
三、安裝Carthage
brew install carthage
複製代碼
四、使用Carthage
cd ~/路徑/項目文件夾 /**進入項目文件夾下*/
touch Cartfile /**建立carthage文件*/
open Cartfile /**打開carthage文件*/
/**輸入如下內容*/
github "NordicSemiconductor/IOS-Pods-DFU-Library" ~> 4.1
github "marmelroy/Zip" ~> 1.1
複製代碼
五、運行Carthage
carthage update --platform iOS /**編譯出iOS版本*/
複製代碼
六、更新framework
cd Carthage/Build/iOS /**framework輸出位置,將老的framework替換掉*/
複製代碼
**注意
nRF Toolbox項目方法變動
[initiator withFirmwareFile:selectedFirmware];/** 舊版本方法 */
initiator = [initiator withFirmware:selectedFirmware];/** 新版本方法 */
複製代碼
DFU v4.2版本API變動兼容舊版,但標爲DEPRECATED
,github項目已經更新。