DTBKit

Static Badge Static Badge

Static Badge

English | 简体中文

What’s this?

A set of personal bundle kits designed to demonstrate best practices in various scenarios;

Focus on painless migration of business code across projects.

When business grows or new projects are developed, we generally want

  • Reuse part of the code
  • Also isolate projects

This topic is very grand. In short, I think

  • Strict modularity is not realistic for independent developers and small teams;

  • The isolation method pioneered by KingFisher is very good, but if you want to extend it to the entire business project, you need to consider more.

This project is some reflection on this issue.

Start

Run example

xcodegen is needed, install it from homebrew firstly:

# install tools
brew install xcodegen

# Use script
cd DTBKit/Scripts
chmod +x ci.sh
./ci.sh
# shell option
b1

# Same as:
cd DTBKit/Example
xcodegen
pod install

Cocoapods

# Add to main project podfile:
source 'https://github.com/darkThanBlack/Specs.git'
# then:
pod 'DTBKit/Core', tag: '0.0.1'

# Or:
pod 'DTBKit/Core', git: 'https://github.com/darkThanBlack/DTBKit', commit: '3f93179af6c2caa1e8bd0c418820947fe1aae899'

Intro

  • Any object can have a special “namespace”. Taking UIView as an example, you can:

    /// 
    UIView().dtb
    /// static / class func
    UIView.dtb
    
  • Then, you can call test func like this:

    UIView().dtb.test()
    
  • For different project / module, you can replace dtb with your own definition:

    UIView().xm.test()
    
  • Add your own methods:

    UIView().xm.test2()
    
  • Most of them is chainable:

    let titleLabel = UILabel().dtb.title("moon").value
    titleLabel.backgroundColor = .white
    

How to use default methods?

Common English words are definitely used up by various programming languages and frameworks, so you need to be very careful in naming, and allow users to agree on the words they are used to.

Currently, the use of the framework only needs to pay attention to the following logic:

  • Object methods start with UIView().dtb
  • Class methods start with UIView.dtb
  • Most objects will implement class methods named create, which are used when creating objects
  • value, all boxed objects will implement this property, used for unpacking

How to replace the name?

For example, the default call looks like this:

if (DTB.app.version == "1.0.0") {
UIView().dtb.toast("is old version")
}

You may want to replace the prefix and property name with XM and xm to match your own project naming conventions:

if (XM.app.version == "1.0.0") {
UIView().xm.toast("is old version")
}

Then, create a new DTBKit+XM.swift file and add the following code:

// === NAMESPACE CONVERT ===

import DTBKit

// - Core

public typealias XM = DTBKit.DTB

public typealias XMKitable = DTBKit.DTBKitable

public typealias XMKitStructable = DTBKit.DTBKitStructable

public typealias XMKitWrapper = DTBKit.DTBKitWrapper

public typealias XMKitStaticWrapper = DTBKit.DTBKitStaticWrapper

extension XMKitable {

public var xm: XMKitWrapper<Self> { return dtb }

public static var xm: XMKitStaticWrapper<Self> { return dtb }
}

extension XMKitStructable {

public var xm: XMKitWrapper<Self> { return dtb }

public static var xm: XMKitStaticWrapper<Self> { return dtb }
}

If you use other sub-repositories at the same time, follow the same pattern:

// - Chain

public typealias XMKitChainable = DTBKit.DTBKitChainable

public typealias XMKitStructChainable = DTBKit.DTBKitStructChainable

public typealias XMKitMutableWrapper = DTBKit.DTBKitMutableWrapper

Now, the new method call can be used within the scope of the DTBKit+XM.swift file.

How to add custom methods?

Refer to the source code and add the corresponding extension to wrapper.

How to modulize?

The control of the scope depends entirely on your control over the extension and protocol declaration files themselves.

For example, if there is a main project Main, with a custom module XM and a module Other, both of which depend on the basic module Basic. First, make the following adjustments to DTBKit+XM.swift in module XM:

public typealias XMKitWrapper = DTBKit.DTBKitWrapper

public typealias XMKitStaticWrapper = DTBKit.DTBKitStaticWrapper

public protocol XMKitable: AnyObject {}

public protocol XMKitStructable {}

extension XMKitable {

    public var xm: XMKitWrapper<Self> {
        return XMKitWrapper(self)
    }

    public static var xm: XMKitStaticWrapper<Self> {
        return XMKitStaticWrapper()
    }
}

extension XMKitStructable {

    public var xm: XMKitWrapper<Self> {
        return XMKitWrapper(self)
    }

    public static var xm: XMKitStaticWrapper<Self> {
        return XMKitStaticWrapper()
    }
}

Now we have a clean protocol:

  • The object still does not have the xm attribute;

  • The xm attribute itself cannot use methods implemented in other modules, including those provided by DTBKit itself;

Next, create CGSize+XM.swift in the XM module and write some business:

// Mark 1
extension CGSize: XMKitStructable {}

// Mark 2
extension XMKitWrapper where Base == CGSize {
    public func area() -> CGFloat {
        return me.width * me.height
    }
}

Obviously, when CGSize can use the xm attribute depends on the scope of Mark 1, and the scope of CGSize The methods of the xm attribute depend on the scope of Mark 2. You can combine the above methods to achieve what you need.

How to use in your private cocoapods?

Move the above code into your private library, and

# private dependency Unable to specify version
ss.dependency 'DTBKit/Core'

# So add source to your private library's main project
source 'https://github.com/darkThanBlack/Specs.git'

# Or:
pod 'DTBKit/Core', git: 'https://github.com/darkThanBlack/DTBKit', commit: '3f93179af6c2caa1e8bd0c418820947fe1aae899'

Unit Tests

Cocoapods test supported:

pod 'DTBKit/Basic', :testspecs => ['Tests']

Xcode > Schemes > Select DTBKit, Command + U .

Blogs

Namespace & Chain

Example

Main dev proj & Test Cases.

Core

Namespace declaration.

Chain

Fast create.

Basic

Basic helper methods.

UIKit

UIKit helper methods.

Author

moonShadow.

License

DTBKit is available under the MIT license. See the LICENSE file for more info.

Docs

jazzy \
  --clean \
  --author darkThanBlack \
  --author_url https://darkthanblack.github.io \
  --source-host github \
  --source-host-url https://github.com/darkThanBlack/DTBKit \
  --exclude "Sources/Chain/*" \
  --output docs/output \
  --theme apple

Edited

Update: 2024/08/14 README - Start