Swift2轉Swift3

接觸swift 已經有一年多的時間了,由最初的OC代碼轉爲 swift 代碼,然後從 swift 2.3 轉爲 swift 3。每次的轉換都感覺是將項目整個的翻新了一遍,每次的轉換代碼都是一次改朝換代。

以下是在代碼改朝換代的時候的一些心得:

在將 OC 代碼轉換爲 swift 代碼的時候,我當時使用的是 xcode7.3。xcode7.3在我的印象中,編寫OC代碼就是聯想功能最差的一個。 所以:

  • 一、在更新swift的時候,在swift文件中,幾乎是不會聯想的,動則就是整個屏幕中的代碼全是白顏色,然後,類名,方法名,都是硬敲出來的。
  • 二、既然是改寫 swift 代碼,那麼就是對swift 不是太瞭解
  • 三、針對一些第三方庫,期望改爲swift版。例如:Masnory -> SnapKit
  • 四、cocoapod 推薦使用 useasframework 的方式集成
  • 五、在 swift 2.3 轉 swift 3.0 的時候,block(閉包)裏面的參數都不要形參,所以參數的前面都是要加上 _ 來防止錯誤。並且 block 非option 的都要加上 @escaping 來修飾
  • 六、在swift中,在iOS8 機型中,所有的控制器在使用 xib 的情況下,都要對初始化方法 init(nibName:nibBundle)這個方法重寫,否則崩潰
  • 七、增加橋接文件

以上幾點都是在轉碼的時候耗費時間比較長、存在坑的。下面說幾點在轉碼過程中總結的一些經驗

  • 一、項目中所使用的到工具類、工廠類、公共類、網絡請求的封裝等等,就是指一些公共模塊。建議在轉碼初期,先將這些文件轉爲 swift。既然能稱爲工具類,那麼一般都是解耦的,所以說,可以新建一個swift項目,將這些工具類轉爲swift文件。這樣做的目的是: 一:工具類的使用量非常大,所以很有必要 swift2.0 / 3.0 化 二:在工具類使用如此頻繁的情況下,如果你的xcode不會聯想,這樣將會使多麼令人頭疼的事情啊!在這點印象頗深
  • 二、更新第三方庫爲 swift 版,因爲雖說允許OC swift混編,但是在類型這個方面兼容性並不是太好。例如:OC中一些 NSArray 的地方,也許我們清楚裏面存放的是字符串,但是如果沒有顯示指定 NSArray <NSString* > * 的話,那麼在swift 中使用起來,你只能得到 Any 類型,使用的時候還要類型綁定,這個屬於類型兼容性。再者一點就是 OC 的方法在聯想方面差的要命
  • 三、cocoapod 使用 useasframework,swift中比較注重 module 的概念,這個也是趨勢,所以同樣是混編,但是仍然要更改爲包的形式
  • 四、關於block 形參的問題,這個需要我們有耐心的一個一個更改
  • 五、在 swift 3.0 中返回值沒有使用那麼會報一個警告,添加一個@discardresult 在方法的前面,放置警告
  • 六、針對第三點中的 包 的概念,我們會發現,例如在使用 snapkit 的時候,只要使用 snp 的地方都要 import SnapKit (當然這個主要是針對swift2.3 -> swift 3.0 並且沒有使用 useasframework )。這個時候會發現每個文件都 import SnapKit 這樣來一下,是多麼痛苦的事情。 下面是我當時新建的 mac 工程整個項目添加 import SnapKit 的方法
func importSnapKit(path: String) {
    
    let manager = FileManager.default
    
    guard let subPaths = try? manager.subpathsOfDirectory(atPath: path) else {
        return
    }
    
    for subPath in subPaths {
        
        let realPath = path + "/\(subPath)"
        
        var isDirectory: ObjCBool = true
        
        if manager.fileExists(atPath: realPath, isDirectory: &isDirectory) {
            
            if realPath.contains("SnapKit") { // 過濾自身
                continue
            }
            
            if !isDirectory.boolValue {
                
                alterSnapKitContent(path: realPath)
            } else {
                
                importSnapKit(path: realPath)
            }
        }
    }
}

func alterSnapKitContent(path: String) {
    
    guard !path.contains("SnapKit") else { // 過濾自身
        return
    }
    
    guard path.contains(".swift") else {
        return
    }
    
    guard var content = try? String.init(contentsOfFile: path) else {
        print("can't get content at path: \(path)")
        return
    }
    
    guard content.contains("snp.") || content.contains("make.") else {
        return
    }
    
    guard !content.contains("import SnapKit") else {
        return
    }
    
    let containUIKit = content.contains("import UIKit")
    
    let containFoundation = content.contains("import Foundation")
    
    if containUIKit {
        
        content = content.replacingOccurrences(of: "import UIKit", with: "import UIKit\n\nimport SnapKit")
        
        _ = try? content.write(toFile: path, atomically: true, encoding: String.Encoding.utf8)
        
        print("has add:\nimport SnapKit\nin file: \(path)")
    } else if containFoundation {
        
        content = content.replacingOccurrences(of: "import Foundation", with: "import Foundation\n\nimport SnapKit")
        
        _ = try? content.write(toFile: path, atomically: true, encoding: String.Encoding.utf8)
        
        print("has add:\nimport SnapKit\nin file: \(path)")
    } else {
        
        content = content.replacingOccurrences(of: "All rights reserved.\n//", with: "All rights reserved.\n//\n\nimport SnapKit")
        
        _ = try? content.write(toFile: path, atomically: true, encoding: String.Encoding.utf8)
        
        print("has replace all right reversed. ")
        
    }
}

// importSnapKit(path: "/Users/*/Desktop/projectname")

大致思路爲: 1、讀取項目中的每個文件,當然除了pod、snapkit 文件夾下面的 2、讀取每個文件中的內容,判斷是否包含snp. 這個字符串,如果存在,則需要導入 import SnapKit 。否則不需要 3、將 import SnapKit 放在 import UIKit 或 import Foundation 或 All rights reserved. 的下面一行 這樣等待半分鐘,將會自動在需要的文件中 import SnapKit

同樣:針對所有的 module 都可以這樣導入,只要將限制條件更改爲合適的即可

轉爲Swift 後:

現在我們公司都是使用swift 編程,swift在代碼編寫方面確實是能夠提高效率,尤其是swift 是面向協議編程,其靈活性不可言喻,並且在 swift 的強語言下,swift 項目是相當穩定的。目前 swift 項目唯一不足之處便是xcode 的編譯速度問題,編譯型語言。我們公司項目是比較大的,每次項目的編譯時間在15分鐘左右,接下來的任務就是如何降低編譯時間。

總體來說推薦大家轉爲swift編程。

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