Skip to content
This repository has been archived by the owner on Jun 13, 2024. It is now read-only.

Commit

Permalink
Update Example for static Cleanse
Browse files Browse the repository at this point in the history
  • Loading branch information
holmes committed Sep 21, 2016
1 parent 729f336 commit 56c8ae7
Show file tree
Hide file tree
Showing 17 changed files with 100 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
884618AF1D9324AD0001ADEB /* AppComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 884618AE1D9324AD0001ADEB /* AppComponent.swift */; };
F69184B31D0DF28A00125872 /* GithubMemberService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69184B21D0DF28A00125872 /* GithubMemberService.swift */; };
F69184B61D0DF2CA00125872 /* GithubRepositoriesService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69184B51D0DF2CA00125872 /* GithubRepositoriesService.swift */; };
F69184BB1D0DF3DD00125872 /* NetworkModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69184BA1D0DF3DD00125872 /* NetworkModule.swift */; };
Expand Down Expand Up @@ -93,6 +94,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
884618AE1D9324AD0001ADEB /* AppComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppComponent.swift; sourceTree = "<group>"; };
F69184B21D0DF28A00125872 /* GithubMemberService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GithubMemberService.swift; sourceTree = "<group>"; };
F69184B51D0DF2CA00125872 /* GithubRepositoriesService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GithubRepositoriesService.swift; sourceTree = "<group>"; };
F69184BA1D0DF3DD00125872 /* NetworkModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkModule.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -229,6 +231,7 @@
F6C9F3631D0BD01700877D0B /* Assets.xcassets */,
F6C9F3651D0BD01700877D0B /* LaunchScreen.storyboard */,
F6C9F3681D0BD01700877D0B /* Info.plist */,
884618AE1D9324AD0001ADEB /* AppComponent.swift */,
F6C9F35C1D0BD01700877D0B /* AppDelegate.swift */,
F6E8782D1D0BD6D7006F3FAB /* RootViewController.swift */,
F69184D41D0F221600125872 /* Pages */,
Expand Down Expand Up @@ -436,6 +439,7 @@
F69184D01D0E33F600125872 /* FakeModeSettings.swift in Sources */,
F69184B31D0DF28A00125872 /* GithubMemberService.swift in Sources */,
F6E878301D0BD911006F3FAB /* SettingsPage.swift in Sources */,
884618AF1D9324AD0001ADEB /* AppComponent.swift in Sources */,
F6E878321D0D1120006F3FAB /* RepositoriesPage.swift in Sources */,
F69184BD1D0DF5DC00125872 /* ErrorOptional.swift in Sources */,
F6E878381D0DD11A006F3FAB /* SplitViewController.swift in Sources */,
Expand Down Expand Up @@ -539,6 +543,7 @@
OTHER_SWIFT_FLAGS = "-DDEBUG $(inherited)";
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 2.3;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
Expand Down Expand Up @@ -578,6 +583,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_SWIFT_FLAGS = "";
SDKROOT = iphoneos;
SWIFT_VERSION = 2.3;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// AppComponent.swift
// CleanseGithubBrowser
//
// Created by holmes on 9/21/16.
// Copyright © 2016 Square, Inc. All rights reserved.
//

import Cleanse

struct ReleaseAppComponent : Cleanse.RootComponent {
typealias Root = PropertyInjector<AppDelegate>
typealias Scope = Singleton

static func configure<B : Binder>(binder binder: B) {
binder.install(module: CoreAppModule.self)

binder.install(module: GithubServicesModule.self)
binder.install(module: NetworkModule.self)
}
}

#if DEBUG

struct FakeAppComponent : Cleanse.RootComponent {
typealias Root = PropertyInjector<AppDelegate>
typealias Scope = Singleton

static func configure<B : Binder>(binder binder: B) {
binder.install(module: CoreAppModule.self)

binder.install(module: FakeGithubServiceModule.self)
binder.install(module: FakeModeSettingsModule.self)
}
}

#endif

struct CoreAppModule : Cleanse.Module {
static func configure<B : Binder>(binder binder: B) {
binder
.bindPropertyInjectionOf(AppDelegate.self)
.to(injector: AppDelegate.injectProperties)

// We want to make it so the app uses "square" as the github user.
binder
.bind()
.tagged(with: GithubOrganizationName.self)
.to(value: "square")

// Bind common dependencies.
binder.install(module: FoundationCommonModule.self)
binder.install(module: UIKitCommonModule.self)

// This will wire up our root view controller.
binder.install(module: RootViewController.Module.self)
binder.install(module: SettingsSplitViewController.Module.self)

binder.install(module: RepositoriesModule.self)
binder.install(module: MembersModule.self)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,25 @@ import Cleanse

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

resetApplication()

// Override point for customization after application launch.
return true
}


func resetApplication() {
// Attempt to build the component we defined below Build returns the `Root` type we defined
let propertyInjector: PropertyInjector<AppDelegate>

// Fake mode makes it easy to test and demo the app. It uses in process versions of the services
if useFakeMode {
propertyInjector = try! Component().withOverrides(overrideModule: FakeModeModule()).build()
// Build and validate the release module to catch bugs sooner.
let _ = try! ComponentFactory.of(ReleaseAppComponent.self)

propertyInjector = try! ComponentFactory.of(FakeAppComponent.self).build()
} else {
propertyInjector = try! Component().build()
propertyInjector = try! ComponentFactory.of(ReleaseAppComponent.self, validate: false).build()
}

// Now inject the properties into ourselves
Expand All @@ -55,58 +53,4 @@ extension AppDelegate {
func injectProperties(window: UIWindow) {
self.window = window
}


/// This is the root component for the app. The Root type is a property injector which populates the root window
struct Component : Cleanse.Component {
typealias Root = PropertyInjector<AppDelegate>

func configure<B : Binder>(binder binder: B) {
binder
.bindPropertyInjectionOf(AppDelegate.self)
.to(injector: AppDelegate.injectProperties)


// We want to make it so the app uses "square" as the github user
binder
.bind()
.tagged(with: GithubOrganizationName.self)
.to(value: "square")


// UIKitCommonModule has useful shared bindings
binder.install(module: UIKitCommonModule())
// This will wire up our root view controller.
binder.install(module: RootViewController.Module())
binder.install(module: SettingsSplitViewController.Module())

binder.install(module: RepositoriesModule())
binder.install(module: MembersModule())

binder.install(module: GithubServicesModule())
binder.install(module: NetworkModule())

binder.install(module: FoundationCommonModule())

binder.install(module: FakeModeSettingsModule())
}
}
}


#if DEBUG

extension AppDelegate {
// This overrides the regular component in debug mode to allow us to use fake services

struct FakeModeModule : OverrideModule {
// We override our component with fakes
typealias Overrides = AppDelegate.Component

func configure<B : Binder>(binder binder: B) {
binder.install(module: FakeGithubServiceModule())
}
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import Cleanse
import UIKit

struct FakeModeSettingsModule : Cleanse.Module {
func configure<B : Binder>(binder binder: B) {

static func configure<B : Binder>(binder binder: B) {
binder.bind().to(factory: FakeModeSettingsSplitViewController.init)
binder.bind().to(factory: FakeModeCell.init)

Expand All @@ -27,17 +26,12 @@ struct FakeModeSettingsModule : Cleanse.Module {
}
}



class FakeModeSettingsSplitViewController : TableViewController {
private let cells: [UITableViewCell]

init(fakeModeCell: FakeModeCell) {

self.cells = [fakeModeCell]

super.init()

self.title = "Fake Mode Settings"
}

Expand All @@ -60,7 +54,6 @@ class FakeModeCell : UITableViewCell {
super.init(style: .Default, reuseIdentifier: nil)

`switch`.on = processInfo.environment["USE_FAKES"] == "YES"

`switch`.addTarget(self, action: #selector(valueChanged), forControlEvents: .TouchUpInside)

textLabel?.text = "Fake Mode Enabled"
Expand All @@ -76,11 +69,9 @@ class FakeModeCell : UITableViewCell {

@objc private func valueChanged() {
let textValue = `switch`.on ? "YES" : "NO"

setenv("USE_FAKES", textValue, 1)

// This is kinda bad, but since fake mode is a hack anywas...

// This is kinda bad, but since fake mode is a hack anyways...
(UIApplication.sharedApplication().delegate! as! AppDelegate).resetApplication()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Cleanse

/// Configure the services to be implemented by fakes
struct FakeGithubServiceModule : Module {
func configure<B : Binder>(binder binder: B) {
static func configure<B : Binder>(binder binder: B) {
/// Make it so when a GithubMembersService is requested, one gets a FakeGithubMembersService
binder
.bind(GithubMembersService.self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Cleanse

/// Module that configures common bindings from the `Foundation` framework
struct FoundationCommonModule : Module {
func configure<B : Binder>(binder binder: B) {
static func configure<B : Binder>(binder binder: B) {
// Make NSProcessInfo available.
binder.bind().to(factory: NSProcessInfo.processInfo)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ struct GithubMembersServiceImpl : GithubMembersService {

/// Hooks up GithubMembersService to its implementation
public struct GithubMembersServiceModule : Module {

public func configure<B : Binder>(binder binder: B) {
public static func configure<B : Binder>(binder binder: B) {
binder
.bind(GithubMembersService.self)
.to(factory: GithubMembersServiceImpl.init)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct GithubRepositoriesServiceImpl : GithubRepositoriesService {

/// Wires up GithubRepositoriesService to its implementation
struct GithubRepositoriesServiceModule : Module {
func configure<B : Binder>(binder binder: B) {
static func configure<B : Binder>(binder binder: B) {
binder
.bind(GithubRepositoriesService.self)
.to(factory: GithubRepositoriesServiceImpl.init)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,21 @@ import Cleanse

/// Wires up common definitions shared across services as well as installing the services's modules
struct GithubServicesModule : Module {
func configure<B : Binder>(binder binder: B) {
binder.install(module: GithubMembersServiceModule())
binder.install(module: GithubRepositoriesServiceModule())
static func configure<B : Binder>(binder binder: B) {
binder.install(module: GithubMembersServiceModule.self)
binder.install(module: GithubRepositoriesServiceModule.self)
}
}




struct GithubBaseURL : Tag {
typealias Element = NSURL
}

/// Represents the github user name we want to query
/// Represents the github user name we want to query.
struct GithubUserName : Tag {
typealias Element = String
}

struct GithubOrganizationName : Tag {
typealias Element = String
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Cleanse

/// A module that configures a tab page on the root view controller as well as on the settings page
struct MembersModule : Cleanse.Module {
func configure<B : Binder>(binder binder: B) {
static func configure<B : Binder>(binder binder: B) {
// Make MembersSettingsSplitViewController available for injection
binder
.bind()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension NSURLSession {

let url = baseURL.URLByAppendingPathComponent(pathComponents.joined(separator: "/"))

return jsonTask(url: url, resultHandler: resultHandler)
return jsonTask(url: url!, resultHandler: resultHandler)
}

private func jsonTask(url url: NSURL, resultHandler: ErrorOptional<AnyObject> -> ()) -> NSURLSessionDataTask {
Expand Down Expand Up @@ -48,9 +48,9 @@ extension NSURLSession {
var url = baseURL.URLByAppendingPathComponent(pathComponents.joined(separator: "/"))

if let query = query {
url = NSURL(string: url.absoluteString + "?" + query)!
url = NSURL(string: url!.absoluteString! + "?" + query)!
}

return jsonTask(url: url) { resultHandler($0.map { $0 as! [[String: AnyObject]] }) }
return jsonTask(url: url!) { resultHandler($0.map { $0 as! [[String: AnyObject]] }) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Cleanse

/// Wires up NSURLSession and friends
struct NetworkModule : Module {
func configure<B : Binder>(binder binder: B) {
static func configure<B : Binder>(binder binder: B) {

binder
.bind()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Cleanse

/// A module that configures a tab page on the root view controller as well as on the settings page
struct RepositoriesModule : Cleanse.Module {
func configure<B : Binder>(binder binder: B) {
static func configure<B : Binder>(binder binder: B) {
// Make RepositoriesViewController available to be injected
binder
.bind()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class RootViewController : UITabBarController {

/// Configures RootViewController
struct Module : Cleanse.Module {
func configure<B : Binder>(binder binder: B) {
static func configure<B : Binder>(binder binder: B) {
binder
.bind(RootViewController.self)
.to(factory: RootViewController.init)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,10 @@ class SettingsSplitViewController : SplitViewController {

/// Module that adds SettingsSplitViewController & friends
struct Module : Cleanse.Module {
func configure<B : Binder>(binder binder: B) {

static func configure<B : Binder>(binder binder: B) {
binder.bind().to(factory: SettingsSplitViewController.init)

binder.bind().to(factory: MasterViewController.init)


// Bind an empty list to Settings in case there aren't any.
binder
.bind(SettingsItem.self)
Expand Down

0 comments on commit 56c8ae7

Please sign in to comment.