InterfaceKit--One line of code to implement interfaces of UIKit,AppKit,and WatchKit in SwiftUI in...

One line of code to implement interfaces of UIKit,AppKit,and WatchKit in SwiftUI interface!

Chinese (Simplified): 中文文档
Code interpretation document: https://github.com/adong666666/InterfaceKitDoc(or this repository's Docs)

The basic idea of InterfaceKit is that we want some user interface abstraction layer that sufficiently encapsulates actually calling UIKit,AppKit,and WatchKit directly. It should be simple enough that common things are easy, but comprehensive enough that complicated things are also easy.

You can check out more about the project direction in the vision document.

                    ┌──────────────┐
                    │   SwiftUI    │
                    └──────▲───────┘
                           │        
┌──────────────────────────┴───────────────────────────┐
│                    InterfaceKit                      │
└───────▲──────────────────▲───────────────────▲───────┘
        │                  │                   │        
┌───────┴──────┐    ┌──────┴───────┐    ┌──────┴───────┐
│     UIKit    │    │    AppKit    │    │   WatchKit   │
└──────────────┘    └──────────────┘    └──────────────┘

Features

  • use interface of UIKit in SwiftUI interface
  • use interface of AppKit in SwiftUI interface
  • use interface of WatchKit in SwiftUI interface

Usage

Universal

For iOS or tvOS:

  • To present UIView.
InterfaceView(MyUIView())
  • To present UIViewController.
InterfaceViewController(MyUIViewController())

For macOS:

  • To present NSView.
NSInterfaceView(MyNSView())
  • To present NSViewController.
NSInterfaceViewController(MyNSViewController())

For watchOS:

  • To present WKInterfaceObject.
WKInterfaceView(MyWKInterfaceObject())

eg.

import SwiftUI
import InterfaceKit

struct MyInterfaceView: View {
    var body: some View {
        ZStack {
            InterfaceViewController(MyViewController())
            InterfaceView(MyView())
            SwiftUIView()
        }
    }
}

#if DEBUG
struct MyInterfaceView_Previews: PreviewProvider {
    static var previews: some View {
        MyInterfaceView()
    }
}
#endif

With Closure

You can do something while presenting SwiftUI view.

  • For Example
InterfaceViewController(MyUIViewController.shared, {
    print("Hello World")
    MyUIViewController.shared.delegate = SomeViewControler.shared
    MyUIViewController.shared.view.alpha = 0.5
    MyUIViewController.shared.view.backgroundColor = .white
    MyUIViewController.someFunction()
    networkRequest()
    JSONParsing()
    downloadFile()
    showProgress()
    makeToast()
    databaseOperation()
    //do something
    ...
})
.navigationBarBackButtonHidden(false)
.navigationBarHidden(false)
.navigationBarTitle(I18n.localizedString("Title"), displayMode: .large)

Multiple platforms

InterfaceKit makes it clearer for multiple platforms programming.

  • For Example
import SwiftUI
import MapKit
import InterfaceKit

let kStr = "Hello World"
#if os(iOS) || os(tvOS)
    typealias OSViewController = UIViewController
    typealias OSView = UILabel
    typealias OSInterfaceView = InterfaceView
    typealias OSInterfaceVC = InterfaceViewController
    let kBounds = UIScreen.main.bounds as CGRect?
#elseif os(macOS)
    typealias OSViewController = NSViewController
    typealias OSView = NSTextField
    typealias OSInterfaceView = NSInterfaceView
    typealias OSInterfaceVC = NSInterfaceViewController
    let kBounds = NSScreen.main?.frame
#endif

@main
struct EApp: App {
    var body: some Scene {
        WindowGroup {
            ZStack {
                #if !os(watchOS)
                    OSInterfaceView(MKMapView())
                    OSInterfaceView(MyView(), { print(kStr) })
                    OSInterfaceVC(MyVC())
                #else
                    WKInterfaceView(WKInterfaceMap(), { print(kStr) })
                #endif
                Text(kStr).foregroundColor(.purple)
            }
        }
    }
}

#if !os(watchOS)
class MyVC: OSViewController {
    #if os(iOS) || os(tvOS)
        override func viewDidLoad() {
            let lbl = MyView()
            lbl.textAlignment = .right
            view.addSubview(lbl)
        }
    #elseif os(macOS)
        override func loadView() { view = MyView() }
    #endif
}

class MyView: OSView {
    override init(frame: CGRect) {
        super.init(frame: CGRect(x: 0, y: kBounds!.height / 2 - 60, width: kBounds!.width, height: 40))
        #if os(iOS) || os(tvOS)
            text = kStr
        #elseif os(macOS)
            stringValue = kStr
        #endif
    }
    
    required init?(coder: NSCoder) { fatalError() }
}
#endif

Requirements

  • iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+
  • Xcode 11+
  • Swift 5.1+

Communication

  • QQ Group: 1027277979
  • If you'd like to contact me, use mail:3440217568@qq.com or QQ:3440217568 or WeChat:adongenjoylife or telephone:15674119605.
  • If you found a bug, and can provide steps to reliably reproduce it, please open an issue.
  • If you have a feature request, please open an issue.
  • If you want to contribute, please submit a pull request.

Status

This project is actively under development. We consider it ready for production use.

Installation

Below is a table that shows which version of InterfaceKit you should use for your Swift version.

Swift InterfaceKit
5.X >= 5.4.0

InterfaceKit supports multiple methods for installing the library in a project.

Copy to your project

Clone the repository by running the following command:

git clone https://github.com/adong666666/InterfaceKit.git --depth=1

Copy the Swift files in InterfaceKit folder to your project.
<div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/copy_files.png" alt="Copy files" /></div>

  • If for iOS or tvOS project, you can copy the file UIInterface.swift.
  • If for macOS project, you can copy the file NSInterface.swift.
  • If for watchOS project, you can copy the file WKInterface.swift.

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. If you have not installed CocoaPods, just install it with the following command:

$ gem install cocoapods

<br />
You need a Podfile to Integrate InterfaceKit into your Xcode project with CocoaPods. If you do not have a Podfile, just create one or use the Podfile provided in PodfileExample folder by this repository. Podfile is as follows.

# Podfile
source 'https://github.com/CocoaPods/Specs.git'
# platform:ios, '13.0'
use_frameworks!
inhibit_all_warnings!

target 'YOUR_TARGET_NAME' do
    pod 'InterfaceKit'
end

# post_install do |installer_representation|
#   installer_representation.pods_project.targets.each do |target|
#     target.build_configurations.each do |config|
#       config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
#     end
#   end
# end

Replace YOUR_TARGET_NAME with your project name.
To integrate InterfaceKit into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'InterfaceKit'

Maybe you have not update CocoaPods, then InterfaceKit may not be found, you can run pod update to update CocoaPods, or just run the following command.

pod 'InterfaceKit', :git => 'https://github.com/adong666666/InterfaceKit.git'
  • If just for iOS or tvOS project, you can specify it in your Podfile:
pod 'InterfaceKit/UIKit'
  • If just for mac project, you can specify it in your Podfile:
pod 'InterfaceKit/AppKit'
  • If just for watchOS project, you can specify it in your Podfile:
pod 'InterfaceKit/WatchKit'
  • If you want to use the newest release of the framework, you can specify it in your Podfile:
pod 'InterfaceKit', :git => 'https://github.com/adong666666/InterfaceKit.git'
  • If you want to use the specific release of the framework, you can specify it like following in your Podfile:
pod 'InterfaceKit', :git => 'https://github.com/adong666666/InterfaceKit.git', :branch => 'master'#, commit: "b7e1facdedd8fe16d04ef5f47c4697e89bad9f27", '~> 5.4.0', :tag => '5.4.0'

Then, in the Podfile directory(Make sure that your Podfile and your xcodeproj file are in the same directory), run the following command:

$ pod install

<div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/PodfileLocation.png" alt="Podfile Location" /></div>

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

  1. To integrate InterfaceKit into your Xcode project using Carthage, specify it in your Cartfile(If you don't have Cartfile, just create one or use the Cartfile provided by this repository in CartfileExample folder):
github "adong666666/InterfaceKit" "master"
  1. Then, in the Cartfile directory(Make sure that your Podfile and your xcodeproj file are in the same directory), run carthage update --use-xcframeworks.
    OR

    • For iOS project, Run carthage update --platform iOS.
    • For macOS project, Run carthage update --platform macOS.
    • For tvOS project, Run carthage update --platform tvOS.
    • For watchOS project, Run carthage update --platform watchOS.
      <div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/CartfileLocation.png" alt="Cartfile Location" /></div>
  2. On your application targets’ "General" settings tab, in the "Frameworks,Libraries,and Embedded Content" section, drag and drop InterfaceKit xcframework (or just select the appropriate framework from xcframework) from the Carthage/Build folder on disk.

Carthage as a Static Library

Carthage defaults to building InterfaceKit as a Dynamic Library.

If you wish to build InterfaceKit as a Static Library using Carthage you may use the script below to manually modify the framework type before building with Carthage:

carthage update InterfaceKit --platform iOS --no-build
sed -i -e 's/MACH_O_TYPE = mh_dylib/MACH_O_TYPE = staticlib/g' Carthage/Checkouts/InterfaceKit/InterfaceKit/InterfaceKit.xcodeproj/project.pbxproj
carthage build InterfaceKit --platform iOS

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler. It is in early development, but InterfaceKit does support its use on supported platforms.

  1. Once you have your Swift package set up, adding InterfaceKit as a dependency is as easy as adding it to the dependencies value of your Package.swift. Then run swift build.
dependencies: [
    .package(url: "https://github.com/adong666666/InterfaceKit.git", .upToNextMajor(from: "5.4.0"))
]

OR

  1. In Xcode, select File > Swift Packages > Add Package Dependency.
  2. Follow the prompts using the URL("https://github.com/adong666666/InterfaceKit.git") for this repository.
    <div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/SwiftPackageManager.png" alt="Swift Package Manager Configuration" /></div>

Manually

If you prefer not to use any of the aforementioned dependency managers, you can integrate InterfaceKit into your project manually.

Embedded Framework

  • Open up Terminal, cd into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:
$ git init
  • Add InterfaceKit as a git submodule by running the following command:
$ git submodule add https://github.com/adong666666/InterfaceKit.git
  • Open the InterfaceKit folder, and drag the InterfaceKit.xcodeproj into the Project Navigator of your application's Xcode project.

    It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.

<div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/drag_framework.png" alt="Drag and drop xcodeproj" /></div>

  • Select the InterfaceKit.xcodeproj in the Project Navigator and verify the deployment target matches that of your application target.

  • Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.

  • In the tab bar at the top of that window, open the "General" panel.

  • Click on the + button under the "Frameworks,Libraries,and Embedded Content" section.

  • You will see the InterfaceKit folder under Workspace. There are InterfaceKit.framework and InterfaceKitTests.xctest in the InterfaceKit folder`

    Click InterfaceKit.framework, and then click Add

<div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/add_framework.png" alt="Add framework" /></div>

  • And that's it!

    The InterfaceKit.framework is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.

Unzip,drag and drop

  1. Unzip the InterfaceKit.xcframework.zip file provided by the repository.
    <div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/unzip.png" alt="Unzip" /></div>

  2. On your application targets’ “General” settings tab, in the "Frameworks,Libraries,and Embedded Content" section, drag and drop the unzipped file InterfaceKit.xcframework (or just select the appropriate framework from InterfaceKit.xcframework).

  • If you use xcfameworks, just drag and drop InterfaceKit.xcframework. InterfaceKit.xcframework supports all four platforms(iOS, macOS, tvOS, watchOS).
    <div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/use_xcframeworks.png" alt="Use xcframeworks" /></div>

  • If you use frameworks, select the appropriate framework from InterfaceKit.xcframework according to the folder name and the platform of your project.
    <div align="center"><img src="https://github.com/adong666666/InterfaceKit/raw/master/Pictures/use_frameworks.png" alt="Use frameworks" /></div>

FAQ

Why use InterfaceKit?

One line of code to implement interfaces of UIKit,AppKit,and WatchKit in SwiftUI interface! InterfaceKit supports for all four platforms(iOS, macOS, tvOS, watchOS). InterfaceKit is constantly updated.

Credits

InterfaceKit is owned and maintained by Saidong Zhang. You can follow him on github at @Github for project updates and releases.

Security Disclosure

If you believe you have identified a security vulnerability with InterfaceKit, you should report it as soon as possible via email to 3440217568@qq.com.

Donations

No donation required, but thanks anyway.

Contributing

Hey! Do you like InterfaceKit? Awesome! We could actually really use your help!

Open source isn't just writing code. InterfaceKit could use your help with any of the following:

  • Finding (and reporting!) bugs.
  • New feature suggestions.
  • Answering questions on issues.
  • Documentation improvements.
  • Reviewing pull requests.
  • Helping to manage issue priorities.
  • Fixing bugs/new features.

If any of that sounds cool to you, send a pull request! After your first contribution, we will add you as a member to the repo so you can merge pull requests and help steer the ship :ship: You can read more details about that in our contributor guidelines.

InterfaceKit's community has a tremendous positive energy, and the maintainers are committed to keeping things awesome. Like in the CocoaPods community, always assume positive intent; even if a comment sounds mean-spirited, give the person the benefit of the doubt.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Adding new source files

If you add or remove a source file from InterfaceKIt, a corresponding change needs to be made to the InterfaceKit.xcworkspace project at the root of this repository. This project is used for Carthage. Don't worry, you'll get an automated warning when submitting a pull request if you forget.

Help us improve InterfaceKit documentation

Whether you’re a core member or a user trying it out for the first time, you can make a valuable contribution to InterfaceKit by improving the documentation. Help us by:

  • sending us feedback about something you thought was confusing or simply missing
  • suggesting better wording or ways of explaining certain topics
  • sending us a pull request via GitHub
  • improving the Chinese documentation

Too wordy about the above? Then just do it.

  • Fork the repository!
  • Create your feature branch: git checkout -b my-new-feature
  • Commit your changes: git commit -am 'Add some feature'
  • Push to the branch: git push origin my-new-feature
  • Submit a pull request
  • Other:
    See CONTRIBUTING.md for details.

License

InterfaceKit is released under the MIT license. See LICENSE for details.

History

See CHANGELOG.md for details.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容

  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,532评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,187评论 4 8
  • 怎么对待生活,它也会怎么对你 人都是哭着来到这个美丽的人间。每个人从来到尘寰到升入天堂,整个生命的历程都是一本书,...
    静静在等你阅读 4,970评论 1 6