【Xcode 10】如何build出可重複利用的framework (純Swift編)

話說世上總是有好人奉獻自己的心血的,像在iOS界的Cocoapods、Android界的Gradle、Nodejs界的NPM…等管理工具,都是能快速取得第三方套件的好地方,在此感謝這些好人們,加一顆星。那我們要如何才能為這個社會盡一份心力呢?從build出私人的framework開始吧。順便工商一下,我自己也有上傳一些簡單的framework在Cocoaspod上,大家覺得不錯也多多支持一下,現在就來製作framework的HelloWorld吧。

產生過程

新增Framework

  • 利用Xcode新增一個Cocoa Touch Framework

取個好名字

設定最低使用的iOS版本

新增一個class檔案

一樣也取個好名字

寫Code

  • 在這個檔案寫入要做成framework的code
//
//  MyImageSDK.swift
//  MySwiftSDK
//

import Foundation

public class ImageProcessor {
    
    var image: UIImage?
    lazy var context: CIContext = { return CIContext(options: nil) }()
    
    public init(image: UIImage?) {
        self.image = image
    }
    
    open func pixellated(scale:Int = 30) -> UIImage? {
        
        if image == nil { return nil }
        
        let filter = CIFilter(name: "CIPixellate")!
        let inputImage = CIImage(image: image!)

        filter.setValue(inputImage, forKey: kCIInputImageKey)
        filter.setValue(scale, forKey: kCIInputScaleKey)
        
        let fullPixellatedImage = filter.outputImage
        let cgImage = context.createCGImage(fullPixellatedImage!, from: fullPixellatedImage!.extent)
        
        return UIImage(cgImage: cgImage!)
    }
    
    open func blured(radius: Int = 40) -> UIImage? {
        
        if image == nil { return nil }
        
        let filter = CIFilter(name: "CIGaussianBlur")!
        let inputImage = CIImage(image: image!)

        filter.setValue(inputImage, forKey: kCIInputImageKey)
        filter.setValue(radius, forKey: kCIInputRadiusKey)

        let outputCIImage = filter.outputImage
        let rect = CGRect(origin: CGPoint.zero, size: image!.size)
        let cgImage = context.createCGImage(outputCIImage!, from: rect)

        return UIImage(cgImage: cgImage!)
    }
}

Build Phases

  • 可以注意一下在Build Phases上的檔案變化

Building

  • 然後就可以Run出Framework了,但是要注意一下,在選裝置的時候會有產生『真機 / 模擬器』Framework的分別,兩個都build一下試試

產生.framework

  • 然後在Products下面就會產生一個.framework的檔案了

查看framework的位置

  • 打開finder看一下會發現,的確會有兩個framework檔

在專案中加入framework

  • 將所產生的framework加入要使用的專案中,在General -> Embedded Binaries中,也要加入該靜態framework,要用真機Run就加入真機的,要用模擬器Run就加入模擬器的

Run Demo

  • 我們就跑個簡單的Demo試試吧
//
//  ViewController.swift
//  SDK_Test
//

import UIKit
import MySwiftSDK

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    
    var defaultImage = #imageLiteral(resourceName: "swift")
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func btn1Click(_ sender: AnyObject) {
        imageView.image = defaultImage
    }
    
    @IBAction func btn2Click(_ sender: AnyObject) {
        imageView.image = ImageProcessor(image: defaultImage).pixellated()
    }
    
    @IBAction func btn3Click(_ sender: AnyObject) {
        imageView.image = ImageProcessor(image: defaultImage).blured()
    }
}

import該framework

影片

動態函式庫?靜態函式庫?

  • 在Build Settings -> All -> Mach-O Type內,可以設定產生的是動態函式庫,還是靜態函式庫