- 包管理:Cocopods
- 核心依赖
- ExSwift
- Framework/Foundation
- 基础扩展 Extension
- Framework/UIKit
- UI扩展 Extension
- Framework/Core
- 工具组件 Tools
- 缓存
- 网络层
- 数据库
- debug: 调试工具
- 工具组件 Tools
- Framework/Module
- 业务服务 Service
- service: 核心服务组件
- 业务组件 Biz Component
- component: UI widget, UI 单一组件,UI 业务组件
- 业务服务 Service
- Framework/Component
- Appearance: 外观工具
- Base: 基础类集
- Component: 组件包装层(避免第三方库命名、规则,污染到业务层)
- Core: 核心工具包装层
pod lib create WYLib
pod lib lint
$ git remote add origin http://git.weiyankeji.cn/APP/ios/WYLib.git
$ git add .
$ git commit -m "Initial commit"
$ git push -u origin master
//tag 值要和podspec中的version一致
$ git tag 0.1.0
//推送tag到服务器上
$ git push --tags
pod spec lint
-
View
-
Between View and ViewController
-
ViewController
-
Between ViewController and Interactor
-
Interactor
-
Scene / per view
-
Configurator (singleton)
-
ViewController
-
ViewController.output -> Interactor (输出Action)
-
ViewController.router -> Router
-
Router
-
Router -> ViewController, dataSource:Interactor, dataDestination:Interactor
-
Interactor <ViewControllerOutput, RouterDataSource, RouterDataDestination>
-
Interactor.output -> Presenter (输出裸数据)
-
Presenter
-
Presenter.output -> ViewController (输出ViewModel)
-
结论:我不喜欢这种,过于碎片,不简洁
- We are not trying to output anything from the ViewController.
- We are assuming the output === Interactor and the architecture loses sense (no component should know about what kind of object its output/input is).
- We dont want the ViewController to know anythyng about Business model.
- We want the Interactor to handle this data but we don't want the ViewController to know anything about it.
-
Magic '_':
-
Variable
-
open,public,internal,fileprivate,private
-
mac-cain13/R.swift, resource
-
typelift/Swiftx, Functional data types and functions
-
keitaoouchi/IoniconsKit, Use ionicons as UIImage / UIFont
-
yonaskolb/SwagGen, Swagger/OpenAPISpec code generator written in Swift
-
thinkloki/swift-open-project, Swift 开源项目分类汇总
// MARK: - TableView
// 1. jeantimex/ios-swift-collapsible-table-section, 可伸缩tableview // 2. SwipeCellKit/SwipeCellKit // 3. Yalantis/PullToRefresh // 4. bcylin/QuickTableViewController // 5. i-schuetz/tableview_infinite, 无限上啦
// MARK: - 数据架构
// 1. ole/SortedArray // 2. lorentey/BTree // 3. https://github.com/objcio/OptimizingCollections // 4. https://github.com/evgenyneu/SigmaSwiftStatistics // 5. https://github.com/LlamaKit/LlamaKit // 6. https://github.com/natecook1000/SortedCollection // 7. https://github.com/IntrepidPursuits/swift-wisdom
// MARK: - Collection
// 1. https://github.com/giulio92/GLTableCollectionView // 2. https://github.com/Ramotion/gliding-collection, 这个用于 分类+列表, pod 'GlidingCollection' // 3. https://github.com/roberthein/BouncyLayout, 这个弹性可以使用:pod "BouncyLayout" // 4. ruslanskorb/RSKCollectionViewRetractableFirstItemLayout, 拖动搜索 // 5. https://github.com/KelvinJin/AnimatedCollectionViewLayout, 几乎是全屏,切换,动画 // 6. https://github.com/ElegantTeam/ETCollectionViewWaterFallLayout // 7. https://github.com/vinnyoodles/mosaic-layout
// MARK: - Switcher
// 1. https://github.com/TBXark/TKSwitcherCollection
// MARK: - 加密
// 1. https://github.com/krzyzanowskim/CryptoSwift
// MARK: - 动画
// 1. https://github.com/YouXianMing/Swift-Animations
// MARK: - _System struct
/// This class adds some useful functions for the App.
struct _Core { // MARK: - Variables
/// Used to store the HasBeenOpened in defaults.
private static let AppHasBeenOpened = "BFAppHasBeenOpened"
// MARK: - Functions
/// Executes a block only if in DEBUG mode.
///
/// [Usage](http://stackoverflow.com/questions/26890537/disabling-nslog-for-production-in-swift-project/26891797#26891797).
public static func debug(_ block: () -> Void) {
#if DEBUG
block()
#endif
}
/// Executes a block only if NOT in DEBUG mode.
public static func release(_ block: () -> Void) {
#if !DEBUG
block()
#endif
}
/// If version is set returns if is first start for that version,
/// otherwise returns if is first start of the App.
///
/// - Parameter version: Version to be checked, you can use the variable BFApp.version to pass the current App version.
/// - Returns: Returns if is first start of the App or for custom version.
public static func isFirstStart(version: String = "") -> Bool {
let key: String = AppHasBeenOpened + "\(version)"
let defaults = UserDefaults.standard
let hasBeenOpened: Bool = defaults.bool(forKey: key)
return !hasBeenOpened
}
/// Executes a block on first start of the App, if version is set it will be for given version.
///
/// Remember to execute UI instuctions on main thread.
///
/// - Parameters:
/// - version: Version to be checked, you can use the variable BFApp.version to pass the current App version.
/// - block: The block to execute, returns isFirstStart.
public static func onFirstStart(version: String = "", block: (_ isFirstStart: Bool) -> Void) {
let key: String
if version == "" {
key = AppHasBeenOpened
} else {
key = AppHasBeenOpened + "\(version)"
}
let defaults = UserDefaults.standard
let hasBeenOpened: Bool = defaults.bool(forKey: key)
if hasBeenOpened != true {
defaults.set(true, forKey: key)
}
block(!hasBeenOpened)
}
/// Set the App setting for a given object and key. The file will be saved in the Library directory.
///
/// - Parameters:
/// - object: Object to set.
/// - objectKey: Key to set the object.
/// - Returns: Returns true if the operation was successful, otherwise false.
@discardableResult
public static func setAppSetting(object: Any, forKey objectKey: String) -> Bool {
return FileManager.default.setSettings(filename: _Core.name, object: object, forKey: objectKey)
}
/// Get the App setting for a given key.
///
/// - Parameter objectKey: Key to get the object.
/// - Returns: Returns the object for the given key.
public static func getAppSetting(objectKey: String) -> Any? {
return FileManager.default.getSettings(filename: _Core.name, forKey: objectKey)
}
}
// MARK: - BFApp extension
/// Extends BFApp with project infos. extension _Core { // MARK: - Variables
/// Return the App name.
public static var name: String = {
return _Core.stringFromInfoDictionary(forKey: "CFBundleDisplayName")
}()
/// Returns the App version.
public static var version: String = {
return _Core.stringFromInfoDictionary(forKey: "CFBundleShortVersionString")
}()
/// Returns the App build.
public static var build: String = {
return _Core.stringFromInfoDictionary(forKey: "CFBundleVersion")
}()
/// Returns the App executable.
public static var executable: String = {
return _Core.stringFromInfoDictionary(forKey: "CFBundleExecutable")
}()
/// Returns the App bundle.
public static var bundle: String = {
return _Core.stringFromInfoDictionary(forKey: "CFBundleIdentifier")
}()
// MARK: - Functions
/// Returns a String from the Info dictionary of the App.
///
/// - Parameter key: Key to search.
/// - Returns: Returns a String from the Info dictionary of the App.
private static func stringFromInfoDictionary(forKey key: String) -> String {
guard let infoDictionary = Bundle.main.infoDictionary, let value = infoDictionary[key] as? String else {
return ""
}
return value
}
}