顯示具有 小技巧 標籤的文章。 顯示所有文章
顯示具有 小技巧 標籤的文章。 顯示所有文章

dyld: lazy symbol binding failed: Symbol not found

最近針對安全性升級調整程式碼,並重新釋出自製的framework套件,結果安裝此套件的專案build得過,但遇到dyld: lazy symbol binding failed: Symbol not found錯誤無法run

最後參考此文章dyld: lazy symbol binding failed: Symbol not found - Swift Kingfisher

雖然不是因為使用Swift Kingfisher造成,但情況大同小異,最終在使用套件的專案之Podfile加上如下語法,並且主動執行一次pod install即可。這段語法用途在於把所有Pod專案的build setting中的Build Libraries for Distribution一次性的設定為YES。要手動設定也是可以。

post_install do |installer|

  installer.pods_project.targets.each do |target|

    target.build_configurations.each do |config|

      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'

    end

  end

end

如果對語法有興趣,可以參考此文瞭解一下CocoaPods Hooks

Swagger: Unable to render this defition

最近用.NET Core開發API專案,本來順順好用的Swagger突然無法提供服務








後來發現是Function Naming造成,例如本來有個方法叫做GetOrders,後來又新增另一個方法叫做GetOrdersAsync,就會讓Swagger用來呈現API定義的頁面失效,要解決此問題不是去調整Swagger,而是調整Function Naming~~不要使用Async結尾的命名方式!!!

原因如下(微軟官方說明)

        從ASP .NET Core 3.0開始,ASP .NET Core MVC會自動把字尾(suffix)的Async移除,routing和link都會受到此預設影響。

解決方法

        方法1:修改性services.AddMvc(options => options.SuppressAsyncSuffixInActionNames = false);

        方法2:Rename Function避免使用Async字尾

Install Package in Sublime Text 2

 成功安裝Package Control後,開始使用它安裝各種plugin套件。

  • 點選選單Preference→Package Control
    輸入Install Package按enter開啟搜尋package的視窗,在視窗內找到想要的plugin安裝
  • 安裝失敗的解決辦法
    請檢查網路是否使用有限制的公司網路,如果你是MAC環境網路通順卻還是不行下載,可參考此篇文章開啟Preference→Package Setting→Package Control→ Settings - User修改,在原始檔案中加入下列設定即可
"downloader_precedence": {
"windows": ["wininet"],
"osx": ["curl", "urllib"],
"linux": ["urllib", "curl", "wget"]
}

Install Package Control in Sublime Text 2

官網安裝教學有自動跟手動二種,自動只適用目前最新版Sublime Text 3,不知道Sublime Text 3何時開始收錢,反正Sublime Text 2夠用,就記錄一下同樣適用2的手動安裝方式。

  1. 開啟Sublime Text 2
  2. 點選選單的Preference→Browse Package...
    會開啟安裝路徑下的Packages資料夾,回到上一層Installed Packages資料夾
  3. 下載package
    在官網下載Package Control.sublime-package,將檔案放到前一步驟的Installed Packages資料夾
  4. 重啟Sublime Text 2
    成功的話選單會新增Package Settings與Package Control二個選項

Cmder安裝與使用

  1. Cmder下載所需安裝檔
    目前只需能執行簡單shell script,不需要Git其他擴充功能,故選擇下載Mini版。
  2. 下載完成解壓至任一資料夾
  3. 設定以系統管理員身份執行(optional)
  4. 寫一個hello script命名為test1.sh
  5. 執行Cmder.exe執行test1.sh,如預期輸出Hello

Installing cURL in Windows

 cURL不存在於Windows,自行安裝過程如下。

  1. 下載對應的壓縮包
    curl for Windows下載
  2. 解壓至想要的路徑
    路徑隨意以個人需求為主,本文將解壓後的curl-7.72.0-win64-mingw資料夾放在C:\curl\
  3. 設定環境變數
    承上,cURL執行檔實際位置在C:\curl\curl-7.72.0-win64-mingw\bin,設定環境變數對後續使用較方便

  4. 檢查是否安裝成功
    cmd視窗輸入curl -V,透過檢查版本號確認環境變數有設定成功可以無痛使用

[iOS]App背景設定滿版圖片

App多數都會在歡迎頁塞個全版的美美背景圖,一般來說做法可以參考這篇如何讓 iOS App 畫面擁有背景圖片

但如果你想要一款背景圖打死所有尺寸,又不希望圖片被拉伸變形,可以在viewDidLoad這樣做

Objective C
self.view.layer.contents = (id)[UIImage imageNamed:@"背景圖檔案名稱"].CGImage;

Swift
self.view.layer.contents = UIImage.init(named:"背景圖檔案名稱")!.cgImage

[iOS]SourceTree error : 'yourXXX.git' does not appear to be a git repository

一個很久沒動的專案,簽入異動至server前,在pull時遭遇如下錯誤
Xcode






Source Tree

後來發現是Remote repository paths不知為何跑掉,參考下圖修改即可

[iOS]限制UITextView的行數與換行規格

UITextView不像UILabel有文字行數、文字斷行規則的屬性可以直接設定,要再往下一層textContainer才能找到相對應的屬性,寫法如下

Swift
textView.textContainer.maximumNumberOfLines = 1
textView.textContainer.lineBreakMode = .byTruncatingTail

Objective C
textView.textContainer.maximumNumberOfLines = 1;
textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;

參考文章

[iOS]stringByAddingPercentEscapesUsingEncoding vs stringByAddingPercentEncodingWithAllowedCharacters

'stringByAddingPercentEscapesUsingEncoding:' is deprecated: first deprecated in iOS 9.0 - Use -stringByAddingPercentEncodingWithAllowedCharacters: instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent since each URL component or subcomponent has different rules for what characters are valid.

如上述文字,不要再用過期的stringByAddingPercentEscapesUsingEncoding,請愛用stringByAddingPercentEncodingWithAllowedCharacters

但stringByAddingPercentEncodingWithAllowedCharacters還要指定你要用哪一款Character Sets,像我的網址如下
http://myhost/User/karen_chang@quantatw.com.png?ModifyDate=2018-06-14T15:30:33.819000
我不希望query string後面的string被解譯錯誤,那就要選用URLQueryAllowedCharacterSet

其他五款的選用時機,請參考Apple Document
不要看網路上都用URLHostAllowedCharacterSet就亂抄,請實際依你的網址選用適合的

[iOS]隱藏UITableView的section header

最近產品畫面用了Grouped UITableView,但卻不想要每個Secton Header都出現,想要永遠隱藏第一個Section header,其他都出現。

照理說
tableView:viewForHeaderInSection 方法 return nil
heightForHeaderInSection 方法 return 0
就可以了

但怎麼試都還是在畫面上看到第一個section Header,後來發現heightForHeaderInSection至少要設一個大於零的數字就好,例如設一個超小的0.1 之類的

[iOS]包裝Swift framework

找到一篇寫得極好的文章(文章1),包出來的framework可以一併套用在模擬器&實機!!
但照著做後,發現自己寫的framework中有引用第三方元件的部分都有問題,無法找到所使用的module(換言之就是import失敗),後來改了Valid Architecture,加上x86_64即可,至於armv7或x86_64這些配置值的定義,可以再參考文章2

文章1
Swift Framework — Ch: 1 . Develop a Swift Framework
文章2
iOS armv7, armv7s, arm64区别与应用32位、64位配置

[iOS]包含closure為參數的function 如何由Objective-C改寫為Swift

記錄一下,如果Objective-C有個方法如下宣告
-(void)POST:(NSString *)userId withCrashTitle:(NSString *)title andContent:(NSString *)content success:(void (^)(BOOL))success failure:(void (^)(NSError *))failure {
}

若改寫為Swift如下
func mailErrorLog(userId:String, withCrashTitle:String, andContent:String, success:(Bool) -> Void, failure:(Error) -> Void) -> Void {
}

參考文章 https://hugolu.gitbooks.io/learn-swift/content/Basic/Closure.html

CocoaPods could not find compatible versions for pod

最近開始用Swift 4開發,想當然third party也要用到最新,以Alamofire、PKHUD為例,我分別需要4.7版、5.0版

        根據Alamofire官方PKHUD官方pod file應該是
        pod 'Alamofire', '~>  4.7'
        pod 'PKHUD', '~> 5.0'










結果pod install會遇到如下錯誤
        [!] CocoaPods could not find compatible versions for pod "Alamofire":
        In Podfile:
           Alamofire (~> 4.7)
        None of your spec sources contain a spec satisfying the dependency: `Alamofire (~> 4.7)`.
















實際上用pod search也的確是找不到Alamofire 4.7版、PKHUD 5.0版,解決方式參考CocoaPods Guides - The PodfileFrom a podspec in the root of a library repo.
修正後的pod file為
        pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :tag => '4.7.0'
        pod 'PKHUD', :git => 'https://github.com/pkluz/PKHUD.git', :branch => 'release/swift4'
   

再pod install成功執行如下
    

[iOS]Alamofire download image

承前篇Alamofire GET request
下載圖片也大同小異,非常簡單~直接把response回來的data轉給UIImageView使用即可

Alamofire.request(logoUrl).responseData(completionHandler: { (response) in               
       switch response.result {
       case .success(let data):
              self.myImageView.image = UIImage(data: data)
       case .failure(let error):
              print(error)                   
       }               
})

[iOS]Swift 4擷取字串

subString在Swift 4被無情的deprecated嘞XD  紀錄一下擷取串的寫法

假設有一個圖片網址logoUrl,下載前我想用該網址提供的檔案名稱A123.png來做後續的存檔檔名,需要將A123.png擷取出來,寫法如下

        let logoUrl = "http://domain/XXX/Company/A123.png"
        let range = logoUrl.range(of: "/", options: .backwards)
        let index = logoUrl.index(after: (range?.lowerBound)!)
     
        let filename1 = String(logoUrl[index...])
        let filename2 = logoUrl.suffix(from: index)
        print(filename1)  // 成功擷取出A123.png
        print(filename2)  // 成功擷取出A123.png

[iOS]使用auth0的JWT元件

不會使用CocoaPods或Carthage者,可在GitHub下載專案後,加入下圖紅色框內檔案即可使用

簡易的decode程式碼範例
    func testJWT() -> Void {
        let testToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3NhbXBsZXMuYXV0aDAuY29tIiwic3ViIjoiYXV0aDB8MTAxMDEwMTAxMCIsImF1ZCI6Imh0dHBzOi8vc2FtcGxlcy5hdXRoMC5jb20iLCJleHAiOjEzNzI2NzQzMzYsImlhdCI6MTM3MjYzODMzNiwianRpIjoicXdlcnR5MTIzNDU2IiwibmJmIjoxMzcyNjM4MzM2fQ.LvF9wSheCB5xarpydmurWgi9NOZkdES5AbNb_UWk9Ew"
        do {
            let jwt = try decode(jwt: testToken)
            print("JWT raw data: \(jwt)")
        } catch let error as NSError {
            print("JWT error: \(error.localizedDescription)")
        }
    }

decode後印出來的字串可以至jwt.io網站驗證是否正確

[Reprinted]isKindOfClass in Swift

Stack Overflow轉載有三種方式,在Swift 4也是不變
Option 1:
if view is UITabBarItem {

}

Option 2:
if view.isKind(of:UITabBarItem.self) {

}

Option 3:
if view.isMember(of:UITabBarItem.self) {

}

The difference between isKind:of and isMember:of is:
●isKind:of returns YES if the receiver is an instance of the exact class, OR if the receiver is an instance of any subclass of the class.
●isMember:of only returns YES if the receiver is an instance of the exact class you're checking against

[iOS] ld: warning: directory not found for option

遇到ld: warning: directory not found for option通常是因為參考的檔案遺失,但最近遇到一個較特殊的狀況,單單只是把專案中的(實體)資料夾改名,就報錯....以我的例子是把資料夾名稱由framework改為Frameworks

解決方式是到專案的「Build Settings→Search Paths→Framework Search Paths」,將不存在的路徑刪除即可