Skip to content

Commit

Permalink
Merge pull request #136 from BarredEwe/swiftPM
Browse files Browse the repository at this point in the history
Added support for swift package manager
  • Loading branch information
mpdifran authored Sep 5, 2021
2 parents 5670226 + 8085afe commit 47df161
Show file tree
Hide file tree
Showing 30 changed files with 397 additions and 404 deletions.
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"object": {
"pins": [
{
"package": "Swinject",
"repositoryURL": "https://github.com/Swinject/Swinject.git",
"state": {
"branch": null,
"revision": "8a76d2c74bafbb455763487cc6a08e91bad1f78b",
"version": "2.7.1"
}
}
]
},
"version": 1
}
38 changes: 38 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// swift-tools-version:5.3
import PackageDescription

let package = Package(
name: "SwinjectStoryboard",
platforms: [
.macOS(.v10_10),
.iOS(.v9),
.tvOS(.v9),
],
products: [
.library(name: "SwinjectStoryboard", targets: ["SwinjectStoryboard"]),
],
dependencies: [
.package(url: "https://github.com/Swinject/Swinject.git", .upToNextMajor(from: "2.7.1")),
],
targets: [
.target(
name: "SwinjectStoryboard-ObjC",
path: "Sources/ObjectiveC",
cSettings: [
.headerSearchPath("Others")
]
),
.target(
name: "SwinjectStoryboard",
dependencies: [
"Swinject",
"SwinjectStoryboard-ObjC"
],
path: "Sources",
exclude: [
"ObjectiveC",
"Info.plist"
]
),
]
)
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ SwinjectStoryboard
[![CocoaPods Version](https://img.shields.io/cocoapods/v/SwinjectStoryboard.svg?style=flat)](http://cocoapods.org/pods/SwinjectStoryboard)
[![License](https://img.shields.io/cocoapods/l/SwinjectStoryboard.svg?style=flat)](http://cocoapods.org/pods/SwinjectStoryboard)
[![Platform](https://img.shields.io/cocoapods/p/SwinjectStoryboard.svg?style=flat)](http://cocoapods.org/pods/SwinjectStoryboard)
[![Swift Version](https://img.shields.io/badge/Swift-3-F16D39.svg?style=flat)](https://developer.apple.com/swift)
[![Swift Version](https://img.shields.io/badge/Swift-5-F16D39.svg?style=flat)](https://developer.apple.com/swift)
[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)

SwinjectStoryboard is an extension of Swinject to automatically inject dependency to view controllers instantiated by a storyboard.

Expand Down Expand Up @@ -45,6 +46,16 @@ pod 'SwinjectStoryboard'

Then run `pod install` command. For details of the installation and usage of CocoaPods, visit [its official website](https://cocoapods.org).

### Swift Package Manager

To integrate using Apple's Swift package manager, add the following as a dependency to your `Package.swift`:

```swift
.package(url: "https://github.com/Swinject/SwinjectStoryboard.git", .upToNextMajor(from: "2.2.0"))
```

and then specify `"SwinjectStoryboard"` as a dependency of the Target in which you wish to use SwinjectStoryboard.

## Usage

Swinject supports automatic dependency injection to view controllers instantiated by `SwinjectStoryboard`. This class inherits `UIStoryboard` (or `NSStoryboard` in case of OS X). To register dependencies of a view controller, use `storyboardInitCompleted` method. In the same way as a registration of a service type, a view controller can be registered with or without a name.
Expand Down
3 changes: 3 additions & 0 deletions Sources/Container+SwinjectStoryboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
// Copyright © 2015 Swinject Contributors. All rights reserved.
//

#if canImport(UIKit)
import UIKit
#endif
import Swinject

#if os(iOS) || os(OSX) || os(tvOS)
Expand Down
18 changes: 18 additions & 0 deletions Sources/DispatchQueue+Once.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Foundation

internal extension DispatchQueue {

private static var _onceTracker: [String] = []

static func once(token: String, block: () -> Void) {
objc_sync_enter(self)
defer { objc_sync_exit(self) }

if _onceTracker.contains(token) {
return
}

_onceTracker.append(token)
block()
}
}
2 changes: 2 additions & 0 deletions Sources/InjectionVerifiable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// Copyright © 2016 Swinject Contributors. All rights reserved.
//

import Foundation

@objc internal protocol InjectionVerifiable: AnyObject {
var wasInjected: Bool { get set }
}
13 changes: 0 additions & 13 deletions Sources/OSX/NSStoryboard+Swizzling.h

This file was deleted.

69 changes: 0 additions & 69 deletions Sources/OSX/NSStoryboard+Swizzling.m

This file was deleted.

41 changes: 41 additions & 0 deletions Sources/OSX/NSStoryboard+Swizzling.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#if canImport(Cocoa)
import Cocoa

extension NSStoryboard {
static func swizzling() {
DispatchQueue.once(token: "swinject.storyboard.init") {
let aClass: AnyClass = object_getClass(self)!

let originalSelector = #selector(NSStoryboard.init(name:bundle:))
let swizzledSelector = #selector(swinject_init(name:bundle:))

let originalMethod = class_getInstanceMethod(aClass, originalSelector)!
let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector)!

let didAddMethod = class_addMethod(aClass, originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod))

guard didAddMethod else {
method_exchangeImplementations(originalMethod, swizzledMethod)
return
}
class_replaceMethod(aClass, swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod))
}
}

@objc class func swinject_init(name: String, bundle: Bundle?) -> NSStoryboard {
guard self == NSStoryboard.self else {
return self.swinject_init(name: name, bundle: bundle)
}
// Instantiate SwinjectStoryboard if NSStoryboard is trying to be instantiated.
if SwinjectStoryboard.isCreatingStoryboardReference {
return SwinjectStoryboard.createReferenced(name: name, bundle: bundle)
} else {
return SwinjectStoryboard.create(name: name, bundle: bundle)
}
}
}
#endif
27 changes: 27 additions & 0 deletions Sources/OSX/_SwinjectStoryboardBase(OSX).swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#if canImport(Cocoa)
import Cocoa
import Swinject

@objcMembers
public class _SwinjectStoryboardBase: NSStoryboard {
public class func _create(_ name: String, bundle storyboardBundleOrNil: Bundle?) -> Self {
let storyboard = perform(#selector(NSStoryboard.init(name:bundle:)), with: name, with: storyboardBundleOrNil)?
.takeUnretainedValue()
return storyboard as! Self
}
}

extension SwinjectStoryboard {
@objc public static func configure() {
NSStoryboard.swizzling()
DispatchQueue.once(token: "swinject.storyboard.setup") {
guard SwinjectStoryboard.responds(to: _Selector("setup")) else { return }
SwinjectStoryboard.perform(_Selector("setup"))
}
}

static func _Selector(_ str: String) -> Selector {
return Selector(str)
}
}
#endif
17 changes: 0 additions & 17 deletions Sources/OSX/_SwinjectStoryboardBase.h

This file was deleted.

17 changes: 0 additions & 17 deletions Sources/OSX/_SwinjectStoryboardBase.m

This file was deleted.

20 changes: 20 additions & 0 deletions Sources/ObjectiveC/Others/SwinjectStoryboard+SetUp.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// SwinjectStoryboard+SetUp.m
// SwinjectStoryboard
//
// Created by Mark DiFranco on 2017-05-27.
// Copyright © 2017 Swinject Contributors. All rights reserved.
//

#import <Foundation/Foundation.h>

__attribute__((constructor)) static void swinjectStoryboardSetupEntry(void) {
Class swinjectStoryboard = NSClassFromString(@"SwinjectStoryboard");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
if ([swinjectStoryboard respondsToSelector:@selector(configure)]) {
[swinjectStoryboard performSelector:@selector(configure)];
}
#pragma clang diagnostic pop
}

2 changes: 2 additions & 0 deletions Sources/RegistrationNameAssociatable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// Copyright © 2015 Swinject Contributors. All rights reserved.
//

import Foundation

@objc internal protocol RegistrationNameAssociatable: AnyObject {
var swinjectRegistrationName: String? { get set }
}
31 changes: 0 additions & 31 deletions Sources/SwinjectStoryboard+SetUp.m

This file was deleted.

7 changes: 7 additions & 0 deletions Sources/SwinjectStoryboard+StoryboardReference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
// Copyright © 2016 Swinject Contributors. All rights reserved.
//

import Foundation
#if canImport(UIKit)
import UIKit
#elseif canImport(Cocoa)
import Cocoa
#endif

internal extension SwinjectStoryboard {

static func pushInstantiatingStoryboard(_ storyboard: SwinjectStoryboard) {
Expand Down
Loading

0 comments on commit 47df161

Please sign in to comment.