nRF芯片設備DFU升級(適配Xcode10.1)

這裏主要參考這個項目:iOS-nRF-Toolbox,它是Nordic公司開發的測試工程,包含一整套nRF設備的測試解決方案。

項目是用Swift寫的,不過之前還是有OC版本的,但是後來由於一些**(不可描述的問題),才變成了現在的純Swift版本。對於使用Swift開發的人員,直接仿照Demo操作即可。如果你是用Swift開發的,那下面的內容你可以不用看了。接下來我就講一下針對OC引用DFU升級的操作步驟和我遇到的問題。

代碼研究

nRF-Toolbox項目包含BGM,HRM,HTM,DFU等多個模塊,我們今天只關注其中的DFU升級模塊。打開項目,在對應的NORDFUViewController.swift中我們能夠看到有三個引用庫 import UIKit,import CoreBluetooth,import iOSDFULibrary,這裏的iOSDFULibrary就是DFU升級的庫,也是解決DFU升級最重要的組件。我們只要把這個庫集成到我們的項目中,就能夠完成nRF設備的DFU升級了。

集成步驟

有兩種方案集成:

  • 通過cocoapods集成
  • 編譯出framework然後把庫導入項目

第一種方案是作者推薦的,但是我試了很久,引入DFULibrary會出現頭文件找不到等一系列問題,無奈只能放棄,如果有人通過這種方式成功,還望告知。下面講的是通過第二種方案的集成。

第一步:導出iOSDFULibrary

這一步是最關鍵也是最容易出問題的,這個庫也是由Swift寫成的,我們將這個庫clone到本地,然後選擇iOSDFULibrary進行編譯

最後生成兩個framework:

  • iOSDFULibrary.framework
  • Zip.framework

這時庫內的代碼已經變成了我們熟悉的OC語言。理論上這個庫應該是沒問題的了,但是事實還是有問題的,見issues#39。作者給出的解決方法是:

1、On your mac please install carthage (instructions)

2、Create a file named cartfile anywhere on your computer

3、add the following content to the file:

github "NordicSemiconductor/IOS-Pods-DFU-Library" ~> 2.1.2
github "marmelroy/Zip" ~> 0.6
複製代碼

1、Open a new terminal and cd to the directory where the file is

2、Enter the command carthage update --platform iOS

3、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];
複製代碼

庫中有三個代理方法DFUProgressDelegateDFUServiceDelegateLoggerDelegate,它們的作用分別爲監視DFU升級進度,DFU升級及藍牙連接狀態,打印狀態日誌。

常見問題

1、selectedFirmware返回nil

DFUFirmware *selectedFirmware = [[DFUFirmware alloc] initWithUrlToZipFile:url];
複製代碼

需要在GeneralEmbeded Binaries選項卡里導入那Zip.frameworkiOSDFULibrary.framework 2、崩潰報錯

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的選項內容刪掉再重新添加一遍即可 3、打包上架時報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
複製代碼

完整OC項目

這個是對應Swift版本用OC寫的完整項目,應該是OC停止維護之前的版本。會有一些bug。在將DFUFramework更新之後,我把它搬到了我的github上,有需要的同學可以下載研究:OC-nRFTool-box


以下爲更新內容,時間:2017.12.26 收到很多關於無法適配Xcode9.2的反饋,因爲最近比較忙沒時間處理,不好意思啦,今天抽出時間來把代碼更新了一下。

Xcode9.2 出現的問題

1、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

2、DFUFirmware *selectedFirmware = [[DFUFirmware alloc] initWithUrlToZipFile:url]; 返回爲空或者崩潰問題

我的測試結果是更新iOSDFULibrary. framework和Zip.framework可以解決以上問題。

解決方案 Carthage

因爲這兩個庫都是通過Swift維護的,所以更新framework最好還是要用適用Swift的方式,包括以後的更新也一樣。所以我推薦用Carthage更新這倆庫,下面是使用Carthage的簡單介紹,詳細的可以看這裏Carthage的安裝和使用。 另外OC-nRFTool-box也已經更新,裏面的Framework可以直接拿來用。

1、安裝brew

 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
複製代碼

2、brew更新

brew update
複製代碼

3、安裝Carthage

brew install carthage
複製代碼

4、使用Carthage

cd ~/路徑/項目文件夾 /**進入項目文件夾下*/
touch Cartfile /**創建carthage文件*/
open Cartfile /**打開carthage文件*/
/**輸入以下內容*/
github "NordicSemiconductor/IOS-Pods-DFU-Library" ~> 4.1
github "marmelroy/Zip" ~> 1.1
複製代碼

5、運行Carthage

carthage update --platform iOS /**編譯出iOS版本*/
複製代碼

6、更新framework

cd Carthage/Build/iOS  /**framework輸出位置,將老的framework替換掉*/
複製代碼

**注意

nRF Toolbox項目方法變更

[initiator withFirmwareFile:selectedFirmware];/** 舊版本方法 */
initiator = [initiator withFirmware:selectedFirmware];/** 新版本方法 */
複製代碼

DFU v4.2版本API變更兼容舊版,但標爲DEPRECATEDgithub項目已經更新。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章