├── .gitignore ├── .swiftlint.yml ├── .travis.yml ├── FRDIntent.podspec ├── FRDIntent.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── FRDIntent.xcscheme │ └── FRDIntentTests.xcscheme ├── FRDIntent ├── Info.plist └── Source │ ├── Core │ ├── FRDIntentTypealias.swift │ ├── RouteManager.swift │ └── Trie.swift │ ├── FRDIntent-Bridging-Header.h │ ├── Intent │ ├── FRDControllerDisplay.swift │ ├── FRDControllerManager.swift │ ├── FRDIntent.swift │ ├── FRDIntentParameters.swift │ ├── FRDIntentReceivable.swift │ ├── FRDPresentationDisplay.swift │ ├── FRDPushDisplay.swift │ └── IntentForResult.swift │ └── URLRoutes │ └── FRDURLRoutes.swift ├── FRDIntentDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── FRDIntentRegisters.plist ├── FRDURLRoutesRegisters.plist ├── FirstViewController.h ├── FirstViewController.m ├── FourthViewController.h ├── FourthViewController.m ├── Info.plist ├── MainViewController.h ├── MainViewController.m ├── SecondViewController.h ├── SecondViewController.m ├── ThirdViewController.h ├── ThirdViewController.m ├── UIViewController+TopViewController.h ├── UIViewController+TopViewController.m └── main.m ├── FRDIntentTests ├── ControllerManagerTests.swift ├── Info.plist ├── MockViewController.swift ├── RouteManagerTests.swift └── URLRoutesTests.swift ├── LICENSE ├── README.md ├── README_EN.md ├── docs ├── Classes.html ├── Classes │ ├── ControllerManager.html │ ├── FRDControllerManager.html │ ├── FRDIntent.html │ ├── FRDIntentParameters.html │ ├── FRDPresentationDisplay.html │ ├── FRDPushDisplay.html │ ├── FRDRouteParameters.html │ ├── FRDURLRoutes.html │ ├── Intent.html │ ├── PresentationDisplay.html │ ├── PushDisplay.html │ └── URLRouter.html ├── Enums.html ├── Enums │ ├── FRDResultCode.html │ └── ResultCode.html ├── Extensions.html ├── Extensions │ └── UIViewController.html ├── Protocols.html ├── Protocols │ ├── ControllerDisplay.html │ ├── FRDControllerDisplay.html │ ├── FRDIntentForResultReceivable.html │ ├── FRDIntentForResultSendable.html │ ├── FRDIntentReceivable.html │ ├── IntentForResultReceivable.html │ ├── IntentForResultSendable.html │ └── IntentReceivable.html ├── css │ ├── highlight.css │ └── jazzy.css ├── docsets │ ├── FRDIntent.docset │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ ├── Documents │ │ │ ├── Classes.html │ │ │ ├── Classes │ │ │ │ ├── ControllerManager.html │ │ │ │ ├── FRDControllerManager.html │ │ │ │ ├── FRDIntent.html │ │ │ │ ├── FRDIntentParameters.html │ │ │ │ ├── FRDPresentationDisplay.html │ │ │ │ ├── FRDPushDisplay.html │ │ │ │ ├── FRDRouteParameters.html │ │ │ │ ├── FRDURLRoutes.html │ │ │ │ ├── Intent.html │ │ │ │ ├── PresentationDisplay.html │ │ │ │ ├── PushDisplay.html │ │ │ │ └── URLRouter.html │ │ │ ├── Enums.html │ │ │ ├── Enums │ │ │ │ ├── FRDResultCode.html │ │ │ │ └── ResultCode.html │ │ │ ├── Extensions.html │ │ │ ├── Extensions │ │ │ │ └── UIViewController.html │ │ │ ├── Protocols.html │ │ │ ├── Protocols │ │ │ │ ├── ControllerDisplay.html │ │ │ │ ├── FRDControllerDisplay.html │ │ │ │ ├── FRDIntentForResultReceivable.html │ │ │ │ ├── FRDIntentForResultSendable.html │ │ │ │ ├── FRDIntentReceivable.html │ │ │ │ ├── IntentForResultReceivable.html │ │ │ │ ├── IntentForResultSendable.html │ │ │ │ └── IntentReceivable.html │ │ │ ├── css │ │ │ │ ├── highlight.css │ │ │ │ └── jazzy.css │ │ │ ├── img │ │ │ │ ├── carat.png │ │ │ │ ├── dash.png │ │ │ │ └── gh.png │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── jazzy.js │ │ │ │ └── jquery.min.js │ │ │ └── undocumented.json │ │ │ └── docSet.dsidx │ └── FRDIntent.tgz ├── img │ ├── carat.png │ ├── dash.png │ └── gh.png ├── index.html ├── js │ ├── jazzy.js │ └── jquery.min.js └── undocumented.json └── install_swiftlint.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | .DS_Store 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata/ 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xcuserstate 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | .build/ 40 | 41 | # CocoaPods 42 | # 43 | # We recommend against adding the Pods directory to your .gitignore. However 44 | # you should judge for yourself, the pros and cons are mentioned at: 45 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 46 | # 47 | # Pods/ 48 | 49 | # Carthage 50 | # 51 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 52 | # Carthage/Checkouts 53 | 54 | Carthage/Build 55 | 56 | # fastlane 57 | # 58 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 59 | # screenshots whenever they are needed. 60 | # For more information about the recommended setup visit: 61 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 62 | 63 | fastlane/report.xml 64 | fastlane/Preview.html 65 | fastlane/screenshots 66 | fastlane/test_output 67 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | included: 2 | - FRDIntent 3 | disabled_rules: 4 | - cyclomatic_complexity 5 | - line_length 6 | - file_length 7 | - function_body_length 8 | - type_body_length 9 | - shorthand_operator 10 | - empty_enum_arguments -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | osx_image: xcode10.2 2 | language: objective-c 3 | install: 4 | - ./install_swiftlint.sh 5 | script: 6 | - | 7 | xcodebuild clean build test \ 8 | -project FRDIntent.xcodeproj \ 9 | -scheme FRDIntent \ 10 | -sdk iphonesimulator \ 11 | -destination 'platform=iOS Simulator,name=iPhone 5s,OS=12.2' \ 12 | ONLY_ACTIVE_ARCH=NO 13 | 14 | - swiftlint -------------------------------------------------------------------------------- /FRDIntent.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "FRDIntent" 4 | s.version = "0.10.4" 5 | s.summary = "FRDIntent can handle the call between view controller" 6 | 7 | s.description = "FRDIntent has two components URLRoutes and Intent, using for calling view controllers inner app or outer app." 8 | s.homepage = "https://github.com/douban/FRDIntent" 9 | s.license = { :type => 'MIT', :text => 'LICENSE' } 10 | s.author = { "lincode" => "guolin@douban.com" } 11 | 12 | s.platform = :ios, "8.0" 13 | s.source = { :git => "https://github.com/douban/FRDIntent.git", :tag => "#{s.version}" } 14 | 15 | s.subspec 'Intent' do |intent| 16 | intent.source_files = 'FRDIntent/Source/*.h','FRDIntent/Source/Intent/**/*.{swift,h,m}', 'FRDIntent/Source/Core/**/*.swift' 17 | intent.frameworks = 'UIKit' 18 | end 19 | 20 | s.subspec 'URLRoutes' do |urlroutes| 21 | urlroutes.source_files = 'FRDIntent/Source/URLRoutes/*.swift' 22 | urlroutes.dependency 'FRDIntent/Intent' 23 | end 24 | 25 | s.default_subspec = 'URLRoutes' 26 | 27 | end 28 | -------------------------------------------------------------------------------- /FRDIntent.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FRDIntent.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FRDIntent.xcodeproj/xcshareddata/xcschemes/FRDIntent.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /FRDIntent.xcodeproj/xcshareddata/xcschemes/FRDIntentTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | 48 | 49 | 51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /FRDIntent/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /FRDIntent/Source/Core/FRDIntentTypealias.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDIntentTypealias.swift 3 | // FRDIntent 4 | // 5 | // Created by bigyelow on 12/12/2016. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public typealias URLRoutesHandler = ([String: Any]) -> Void 12 | 13 | typealias RoutePathNodeValueType = (FRDIntentReceivable.Type?, URLRoutesHandler?) 14 | -------------------------------------------------------------------------------- /FRDIntent/Source/Core/RouteManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RouteManager.swfit 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/30/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | RouteManager offers the public operation interface of route path search tree. 13 | 14 | We maintains two register systems in one trie tree for saving space. 15 | Every tree node's value is a tuple (clazz, handler). 16 | The clazz is for FRDIntent's register. 17 | The handler is for URLRoute's register. 18 | */ 19 | class RouteManager { 20 | 21 | static let URLRouteURL = "URLRouteURL" 22 | 23 | static let sharedInstance = RouteManager() 24 | fileprivate var routes = Trie() 25 | 26 | // MARK: - Register 27 | 28 | /** 29 | Register url for save the clazz in the routes. 30 | 31 | - parameter url: The path for search the storage position. 32 | - parameter clazz: The clazz to be saved. 33 | */ 34 | @discardableResult func register(_ url: URL, clazz: FRDIntentReceivable.Type) -> Bool { 35 | if let node = routes.searchNodeWithoutMatchPlaceholder(with: url), let (_, handler) = node.value { 36 | node.value = (clazz, handler) 37 | return true 38 | } 39 | // not find it, insert 40 | return routes.insert((clazz, nil), with: url) 41 | } 42 | 43 | /** 44 | Register url for save the handler in the routes. 45 | 46 | - parameter url: The path for search the storage position. 47 | - parameter hanlder: The handler to be saved. 48 | */ 49 | @discardableResult func register(_ url: URL, handler: @escaping URLRoutesHandler) -> Bool { 50 | if let node = routes.searchNodeWithoutMatchPlaceholder(with: url), let (clazz, _) = node.value { 51 | node.value = (clazz, handler) 52 | return true 53 | } 54 | // not find it, insert 55 | return routes.insert((nil, handler), with: url) 56 | } 57 | 58 | // MARK: - Unregister 59 | 60 | /** 61 | Unregister url 62 | 63 | - parameter url: The url to be unregistered 64 | */ 65 | func unregisterController(with url: URL) { 66 | guard let node = routes.searchNodeWithoutMatchPlaceholder(with: url) else { return } 67 | if let (_, handler) = node.value { 68 | if handler == nil { 69 | node.value = nil 70 | routes.remove(node) 71 | } else { 72 | node.value = (nil, handler) 73 | } 74 | } 75 | } 76 | 77 | func unregisterHandler(with url: URL) { 78 | guard let node = routes.searchNodeWithoutMatchPlaceholder(with: url) else { return } 79 | if let (clazz, _) = node.value { 80 | if clazz == nil { 81 | node.value = nil 82 | routes.remove(node) 83 | } else { 84 | node.value = (clazz, nil) 85 | } 86 | } 87 | } 88 | 89 | /** 90 | Check the url is registered or not. 91 | 92 | - parameter url: The url to be checked. 93 | */ 94 | func hasRegisteredController(with url: URL) -> Bool { 95 | guard let node = routes.searchNodeWithMatchPlaceholder(with: url) else { return false } 96 | if let (clazz, _) = node.value { 97 | if clazz == nil { 98 | return false 99 | } 100 | } 101 | return true 102 | } 103 | 104 | func hasRegisteredHandler(with url: URL) -> Bool { 105 | guard let node = routes.searchNodeWithMatchPlaceholder(with: url) else { return false } 106 | if let (_, handler) = node.value { 107 | if handler == nil { 108 | return false 109 | } 110 | } 111 | return true 112 | } 113 | 114 | // MARK: - Search 115 | 116 | /** 117 | Search the controller in in the routes whith the url. 118 | 119 | - parameter url: The url for search the clazz. 120 | 121 | - returns: A tuple with parameters and clazz. 122 | */ 123 | func searchController(with url: URL) -> ([String: Any], FRDIntentReceivable.Type?) { 124 | if let node = routes.search(with: url), let (clazz, _) = node.value { 125 | let param = routes.extractMatchedPattern(from: url, resultNode: node) 126 | return (extractParameters(from: url, defaultParam: param), clazz) 127 | } else { 128 | return (extractParameters(from: url), nil) 129 | } 130 | } 131 | 132 | /** 133 | Search the handler in in the route whith the url. 134 | 135 | - parameter url: The url for search the handler. 136 | 137 | - returns: A tuple with parameters and handler. 138 | */ 139 | func searchHandler(with url: URL) -> ([String: Any], URLRoutesHandler?) { 140 | if let node = routes.search(with: url), let (_, handler) = node.value { 141 | let param = routes.extractMatchedPattern(from: url, resultNode: node) 142 | return (extractParameters(from: url, defaultParam: param), handler) 143 | } else { 144 | return (extractParameters(from: url), nil) 145 | } 146 | } 147 | 148 | // MARK: - Private Methods 149 | private func extractParameters(from url: URL, defaultParam: [String: Any] = [:]) -> [String: Any] { 150 | 151 | // Extract placeholder parameters 152 | var params = defaultParam 153 | 154 | // Add url to params 155 | params.updateValue(url, forKey: RouteManager.URLRouteURL) 156 | 157 | // Add queries to params 158 | if let queryItems = url.queryItems { 159 | for queryItem in queryItems { 160 | if let value = queryItem.value { 161 | params.updateValue(value, forKey: queryItem.name) 162 | } 163 | } 164 | } 165 | 166 | // Add fragment to params 167 | if let fragment = url.fragment { 168 | params.updateValue(fragment, forKey: "fragment") 169 | } 170 | 171 | return params 172 | } 173 | 174 | } 175 | -------------------------------------------------------------------------------- /FRDIntent/Source/FRDIntent-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // FRDIntent-Bridging-Header.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 07/12/2016. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | #ifndef FRDIntent_Bridging_Header_h 10 | #define FRDIntent_Bridging_Header_h 11 | 12 | #endif /* FRDIntent_Bridging_Header_h */ 13 | -------------------------------------------------------------------------------- /FRDIntent/Source/Intent/FRDControllerDisplay.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDControllerDisplay.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/25/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | /** 12 | The protocol to abstract the way of how the destination view controller displays. 13 | */ 14 | @objc public protocol FRDControllerDisplay { 15 | 16 | /** 17 | How to display the destination view controller. 18 | 19 | - parameter source: The source view controller. 20 | - parameter destination: The destination view controller. 21 | */ 22 | func displayViewController(from source: UIViewController, to destination: UIViewController) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /FRDIntent/Source/Intent/FRDIntent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDIntent.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/25/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | An intent is an abstract description of an operation to be performed. 13 | It can be used with startController to launch a view controller. 14 | */ 15 | public class FRDIntent: NSObject { 16 | 17 | /** 18 | The url for identify the destination view controller. 19 | */ 20 | @objc public var url: URL? 21 | 22 | /** 23 | The destination view controller's class type. 24 | */ 25 | @objc public var receiveClass: FRDIntentReceivable.Type? 26 | 27 | /** 28 | The way of how to display the new view controller. 29 | */ 30 | @objc public var controllerDisplay: FRDControllerDisplay? 31 | 32 | /** 33 | The extra data to inform the destination view controller. Read-only. 34 | */ 35 | @objc public fileprivate(set) var extras = [String: Any]() 36 | 37 | /** 38 | Initializer with the destination view controller's class type. 39 | 40 | - parameter clazz: The destination view controller's class type. 41 | */ 42 | @objc public init(clazz: FRDIntentReceivable.Type) { 43 | self.receiveClass = clazz 44 | } 45 | 46 | /** 47 | Initializer with the url for identify the destination view controller. 48 | 49 | - parameter url: The url for identify the destination view controller. 50 | */ 51 | @objc public init(url: URL) { 52 | self.url = url 53 | } 54 | 55 | /** 56 | Initializer with the url for identify the destination view controller. 57 | 58 | - parameter pathIdentifier: The path identifier for identify the destination view controller. 59 | The format is url path. 60 | */ 61 | @objc public convenience init(pathIdentifier: String) { 62 | self.init(url: URL(string: pathIdentifier)!) 63 | } 64 | 65 | /** 66 | Put the extra data into the intent. 67 | 68 | - parameter name: key 69 | - parameter value: value 70 | */ 71 | @objc public func putExtraName(_ name: String, withValue value: Any) { 72 | self.extras[name] = value 73 | } 74 | 75 | /** 76 | Put the extras datas into the intent. 77 | 78 | - parameter datas: the data dictionary. 79 | */ 80 | @objc public func putExtraDatas(_ datas: [String: Any]) { 81 | for (key, value) in datas { 82 | self.extras[key] = value 83 | } 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /FRDIntent/Source/Intent/FRDIntentParameters.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDIntentParameters.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 04/01/2017. 6 | // Copyright © 2017 Douban Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Open the parameters to public. 13 | * Defined as a class because of the usage of Objective-C. 14 | */ 15 | public class FRDIntentParameters: NSObject { 16 | 17 | /// The usual keys to get the infomation from extras of intent. 18 | @objc public static let title = "FRDIntentTitleKey" 19 | @objc public static let hidesBottomBarWhenPushed = "FRDIntentHidesBottomBarWhenPushedKey" 20 | @objc public static let URL = RouteManager.URLRouteURL 21 | 22 | // Extract the ":id" pattern match from intent's extras. 23 | // swiftlint:disable:next identifier_name 24 | @objc public static let id = "id" 25 | } 26 | -------------------------------------------------------------------------------- /FRDIntent/Source/Intent/FRDIntentReceivable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDIntentReceivable.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/25/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | The protocol to abstract the view controller that can receive the Intent. 13 | */ 14 | @objc public protocol FRDIntentReceivable { 15 | 16 | /** 17 | Initialzier with extra data. 18 | 19 | - parameter extras: The extra data. 20 | */ 21 | init?(extras: [String: Any]) 22 | } 23 | -------------------------------------------------------------------------------- /FRDIntent/Source/Intent/FRDPresentationDisplay.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDPresentationDisplay.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/25/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | /** 12 | The way of display view controllers with present. 13 | It calls presentViewController(viewController: UIViewController, animated: Bool) 14 | */ 15 | open class FRDPresentationDisplay: NSObject, FRDControllerDisplay { 16 | 17 | /** 18 | How to display the destination view controller. 19 | 20 | - parameter source: The source view controller. 21 | - parameter destination: The destination view controller. 22 | */ 23 | open func displayViewController(from source: UIViewController, to destination: UIViewController) { 24 | let nav = UINavigationController(rootViewController: destination) 25 | source.present(nav, animated: true, completion: nil) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /FRDIntent/Source/Intent/FRDPushDisplay.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDPushDisplay.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/25/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | /** 12 | The way of display view controllers with push. 13 | It calls pushViewController(viewController: UIViewController, animated: Bool) 14 | */ 15 | open class FRDPushDisplay: NSObject, FRDControllerDisplay { 16 | 17 | /** 18 | How to display the destination view controller. 19 | 20 | - parameter source: The source view controller. 21 | - parameter destination: The destination view controller. 22 | */ 23 | open func displayViewController(from source: UIViewController, to destination: UIViewController) { 24 | if let navigationController = source.navigationController { 25 | navigationController.pushViewController(destination, animated: true) 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /FRDIntent/Source/Intent/IntentForResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IntentForResult.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/29/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | The resultCode's possible values: 13 | */ 14 | @objc public enum FRDResultCode: Int { 15 | 16 | /// Ok: For successful result. 17 | // swiftlint:disable:next identifier_name 18 | case ok 19 | /// Canceled: For the canceled operation. 20 | case canceled 21 | /// FirstUser: For the custom define operation. 22 | case firstUser 23 | 24 | } 25 | 26 | /** 27 | The protocol to abstract the view controller that can send the Intent asking for the result from the destination. 28 | */ 29 | @objc public protocol FRDIntentForResultSendable { 30 | 31 | /** 32 | When the result returns, this method will be called. 33 | 34 | - parameter requestCode: The integer request code originally supplied to startControllerForResult(), 35 | allowing you to identify who this result came from. 36 | - parameter resultCode: The result code returned by the child conroller. 37 | - parameter data: A dictionary which can return result data to the caller. 38 | */ 39 | func controllerDidReturn(withReqeustCode requestCode: Int, resultCode: FRDResultCode, data: [String: Any]) 40 | 41 | } 42 | 43 | /** 44 | The protocol to abstract the view controller that can receive the Intent asking for the result from the destination. 45 | */ 46 | @objc public protocol FRDIntentForResultReceivable: FRDIntentReceivable { 47 | 48 | // var requestCode: Int? { get set } 49 | // var delegate: IntentForResultSendable? { get set } 50 | 51 | /// The integer request code originally supplied to startControllerForResult(), 52 | /// allowing you to identify who this result came from. 53 | func setRequestCode(_ requestCode: Int) 54 | 55 | /// The source view controller 56 | func setDelegate(_ delegate: FRDIntentForResultSendable?) 57 | } 58 | -------------------------------------------------------------------------------- /FRDIntent/Source/URLRoutes/FRDURLRoutes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDURLRoutes.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/31/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | /** 12 | FRDURLRoutes is a way to manage URL routes and invoke them from a URL. 13 | */ 14 | public class FRDURLRoutes: NSObject { 15 | 16 | /// Singleton instance of URLRoutes. 17 | @objc public static let sharedInstance = FRDURLRoutes() 18 | 19 | private let routeManager = RouteManager.sharedInstance 20 | 21 | /** 22 | Registers a url for calling handler blocks. 23 | 24 | - parameter url: The url to be registered. 25 | - parameter handler: The handler to be registered, and will be called while routed. 26 | 27 | - returns: True if it registers successfully. 28 | */ 29 | @objc(registerURL:handler:) 30 | @discardableResult public func register(_ url: URL, handler: @escaping URLRoutesHandler) -> Bool { 31 | return routeManager.register(url, handler: handler) 32 | } 33 | 34 | /** 35 | Routes a URL, calling handler blocks (for patterns that match URL) until one returns YES. 36 | 37 | - parameter url: The url for search. 38 | 39 | - returns: True if handler block is found and called, false if handler block is not found. 40 | */ 41 | @objc public func route(_ url: URL) -> Bool { 42 | let (params, handler) = routeManager.searchHandler(with: url) 43 | if let handler = handler { 44 | handler(params) 45 | return true 46 | } 47 | return false 48 | } 49 | 50 | /** 51 | Tells if FRDURLRoutes can route a given url. 52 | 53 | - parameter url: The url for search. 54 | 55 | - returns: True if a handler can be found for the given url. 56 | */ 57 | @objc public func canRoute(_ url: URL) -> Bool { 58 | return routeManager.hasRegisteredHandler(with: url) 59 | } 60 | 61 | /** 62 | Unregister url 63 | 64 | - parameter url: The url to be unregistered 65 | */ 66 | @objc(unregisterURL:) 67 | public func unregister(_ url: URL) { 68 | routeManager.unregisterHandler(with: url) 69 | } 70 | } 71 | 72 | public extension FRDURLRoutes { 73 | 74 | /** 75 | Registers a url for calling handler blocks. 76 | 77 | - parameter url: The url to be registered. 78 | - parameter clazz: The UIViewController's class to be registered, 79 | and this view controller will be started while routed. 80 | 81 | - returns: True if it registers successfully. 82 | */ 83 | @objc(registerURL:clazz:) 84 | @discardableResult func register(_ url: URL, clazz: FRDIntentReceivable.Type) -> Bool { 85 | 86 | let resultForIntent = FRDControllerManager.sharedInstance.register(url, clazz: clazz) 87 | let resultForRoute = register(url) { (params: [String: Any]) in 88 | guard let url = params[RouteManager.URLRouteURL] as? URL else { return } 89 | let intent = FRDIntent(url: url) 90 | if let topViewController = UIApplication.topViewController() { 91 | FRDControllerManager.sharedInstance.startController(from: topViewController, with: intent) 92 | } 93 | } 94 | 95 | return (resultForRoute && resultForIntent) 96 | } 97 | 98 | /** 99 | Registers with a plist file. 100 | 101 | - parameter path: The plistFile path. 102 | 103 | - returns: True if it registers successfully. 104 | */ 105 | @objc @discardableResult func register(contentsOfFile path: String) -> Bool { 106 | 107 | guard let registers: NSDictionary = NSDictionary(contentsOfFile: path) else { 108 | return false 109 | } 110 | 111 | for (url, className) in registers { 112 | 113 | guard let url = url as? String, let className = className as? String else { 114 | return false 115 | } 116 | 117 | if let clazz = NSClassFromString(className) as? FRDIntentReceivable.Type { 118 | let result = register(URL(string: url)!, clazz: clazz) 119 | if !result { 120 | return false 121 | } 122 | } 123 | 124 | } 125 | return true 126 | } 127 | 128 | } 129 | 130 | fileprivate extension UIApplication { 131 | 132 | class func topViewController(from base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) 133 | -> UIViewController? { 134 | 135 | if let nav = base as? UINavigationController { 136 | return topViewController(from: nav.visibleViewController) 137 | } 138 | if let tab = base as? UITabBarController { 139 | if let selected = tab.selectedViewController { 140 | return topViewController(from: selected) 141 | } 142 | } 143 | if let presented = base?.presentedViewController { 144 | return topViewController(from: presented) 145 | } 146 | return base 147 | 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /FRDIntentDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /FRDIntentDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | #import "MainViewController.h" 14 | #import "FirstViewController.h" 15 | #import "SecondViewController.h" 16 | #import "ThirdViewController.h" 17 | #import "UIViewController+TopViewController.h" 18 | 19 | @interface AppDelegate () 20 | 21 | @end 22 | 23 | @implementation AppDelegate 24 | 25 | 26 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 27 | // Override point for customization after application launch. 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 30 | self.window.backgroundColor = [UIColor whiteColor]; 31 | 32 | MainViewController *controller = [[MainViewController alloc] init]; 33 | 34 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:controller]; 35 | 36 | self.window.rootViewController = nav; 37 | 38 | [self.window makeKeyAndVisible]; 39 | 40 | [self configurationRoutes]; 41 | return YES; 42 | } 43 | 44 | - (void)applicationWillResignActive:(UIApplication *)application { 45 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 46 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 47 | } 48 | 49 | - (void)applicationDidEnterBackground:(UIApplication *)application { 50 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 51 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 52 | } 53 | 54 | - (void)applicationWillEnterForeground:(UIApplication *)application { 55 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 56 | } 57 | 58 | - (void)applicationDidBecomeActive:(UIApplication *)application { 59 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 60 | } 61 | 62 | - (void)applicationWillTerminate:(UIApplication *)application { 63 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 64 | } 65 | 66 | //iOS 9+ 67 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 68 | return [[FRDURLRoutes sharedInstance] route:url]; 69 | } 70 | 71 | //iOS 8 72 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 73 | return [[FRDURLRoutes sharedInstance] route:url]; 74 | } 75 | 76 | - (void)configurationRoutes { 77 | 78 | // Internal call register 79 | //[[FRDControllerManager sharedInstance] registerWithUrl: [NSURL URLWithString: @"/user/:userId"] clazz: [FirstViewController class]]; 80 | //[[FRDControllerManager sharedInstance] registerWithUrl: [NSURL URLWithString: @"/story/:storyId"] clazz: [SecondViewController class]]; 81 | //[[FRDControllerManager sharedInstance] registerWithUrl: [NSURL URLWithString: @"/user/:userId/story/:storyId"] clazz: [ThirdViewController class]]; 82 | 83 | // Internal call register by plist 84 | NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"FRDIntentRegisters" ofType:@"plist"]; 85 | [[FRDControllerManager sharedInstance] registerWithContentsOfFile:plistPath]; 86 | 87 | 88 | 89 | // External call register 90 | [[FRDURLRoutes sharedInstance] registerURL:[NSURL URLWithString:@"/user/:userId/story/:storyId"] 91 | handler:^(NSDictionary *params) 92 | { 93 | NSURL *url = [params objectForKey:FRDIntentParameters.URL]; 94 | FRDIntent *intent = [[FRDIntent alloc] initWithUrl:url]; 95 | intent.controllerDisplay = [[FRDPresentationDisplay alloc] init]; 96 | UIViewController *topViewController = [UIViewController topViewController]; 97 | if (topViewController) { 98 | [[FRDControllerManager sharedInstance] startControllerFrom:topViewController with:intent]; 99 | } 100 | }]; 101 | 102 | 103 | // External call register 104 | //[[FRDURLRoutes sharedInstance] registerWithUrl:[NSURL URLWithString: @"/story/:storyId"] 105 | // clazz:[SecondViewController self]]; 106 | 107 | // External call register by plist 108 | NSString* routesPlistPath = [[NSBundle mainBundle] pathForResource:@"FRDURLRoutesRegisters" ofType:@"plist"]; 109 | [[FRDURLRoutes sharedInstance] registerWithContentsOfFile:routesPlistPath]; 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /FRDIntentDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /FRDIntentDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FRDIntentDemo/FRDIntentRegisters.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | /subject/:subjectId 6 | FourthViewController 7 | /user/:userId/story/:storyId 8 | ThirdViewController 9 | /story/:storyId 10 | SecondViewController 11 | /user/:userId 12 | FirstViewController 13 | 14 | 15 | -------------------------------------------------------------------------------- /FRDIntentDemo/FRDURLRoutesRegisters.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | /user/:userId 6 | FirstViewController 7 | /story/:storyId 8 | SecondViewController 9 | 10 | 11 | -------------------------------------------------------------------------------- /FRDIntentDemo/FirstViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import 12 | 13 | @interface FirstViewController : UIViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /FRDIntentDemo/FirstViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.m 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import "FirstViewController.h" 10 | 11 | 12 | @interface FirstViewController () 13 | 14 | @property (nonatomic, strong) NSDictionary *data; 15 | 16 | @end 17 | 18 | @implementation FirstViewController 19 | 20 | - (id)initWithExtras:(NSDictionary *)extras { 21 | self = [super init]; 22 | if (self) { 23 | _data = extras; 24 | [self setupExtras:extras]; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | self.view.backgroundColor = [UIColor whiteColor]; 32 | 33 | UILabel *numberLabel = [[UILabel alloc] init]; 34 | numberLabel.frame = CGRectMake(20, 100, self.view.bounds.size.width - 40, 400); 35 | numberLabel.textAlignment = NSTextAlignmentCenter; 36 | numberLabel.numberOfLines = 0; 37 | if (self.data) { 38 | numberLabel.text = [NSString stringWithFormat:@"%@", self.data]; 39 | } 40 | [self.view addSubview:numberLabel]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /FRDIntentDemo/FourthViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FourthViewController.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 03/01/2017. 6 | // Copyright © 2017 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FourthViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /FRDIntentDemo/FourthViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FourthViewController.m 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 03/01/2017. 6 | // Copyright © 2017 Douban Inc. All rights reserved. 7 | // 8 | @import FRDIntent; 9 | #import "FourthViewController.h" 10 | #import "UIViewController+TopViewController.h" 11 | 12 | @interface FourthViewController () 13 | 14 | @property (nonatomic, strong) NSDictionary *data; 15 | 16 | @end 17 | 18 | @implementation FourthViewController 19 | 20 | - (id)initWithExtras:(NSDictionary *)extras { 21 | self = [super init]; 22 | if (self) { 23 | _data = extras; 24 | } 25 | return self; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /FRDIntentDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleTypeRole 25 | Editor 26 | CFBundleURLName 27 | frdintent.com 28 | CFBundleURLSchemes 29 | 30 | frdintent 31 | 32 | 33 | 34 | CFBundleVersion 35 | 1 36 | LSRequiresIPhoneOS 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UIStatusBarTintParameters 45 | 46 | UINavigationBar 47 | 48 | Style 49 | UIBarStyleDefault 50 | Translucent 51 | 52 | 53 | 54 | UISupportedInterfaceOrientations 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationLandscapeLeft 58 | UIInterfaceOrientationLandscapeRight 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /FRDIntentDemo/MainViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/12/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface MainViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /FRDIntentDemo/MainViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.m 3 | // FRDFRDIntent 4 | // 5 | // Created by GUO Lin on 9/12/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | #import 9 | 10 | #import "MainViewController.h" 11 | #import "SecondViewController.h" 12 | #import "ThirdViewController.h" 13 | #import "FourthViewController.h" 14 | 15 | @interface MainViewController () 16 | 17 | @end 18 | 19 | @implementation MainViewController 20 | 21 | - (void)viewDidLoad 22 | { 23 | [super viewDidLoad]; 24 | self.view.backgroundColor = [UIColor whiteColor]; 25 | 26 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 27 | button.frame = CGRectMake(20, 100, self.view.bounds.size.width - 40, 44); 28 | [button setTitle:@"By Uri" forState:UIControlStateNormal]; 29 | button.backgroundColor = [UIColor greenColor]; 30 | [button addTarget:self 31 | action:@selector(gotoFirstViewController) 32 | forControlEvents:UIControlEventTouchUpInside]; 33 | [self.view addSubview:button]; 34 | 35 | UIButton *secondbutton = [UIButton buttonWithType:UIButtonTypeCustom]; 36 | secondbutton.frame = CGRectMake(20, 200, self.view.bounds.size.width - 40, 44); 37 | [secondbutton setTitle:@"By Class Name" forState:UIControlStateNormal]; 38 | secondbutton.backgroundColor = [UIColor greenColor]; 39 | [secondbutton addTarget:self 40 | action:@selector(gotoSecondViewController) 41 | forControlEvents:UIControlEventTouchUpInside]; 42 | [self.view addSubview:secondbutton]; 43 | 44 | UIButton *thirdbutton = [UIButton buttonWithType:UIButtonTypeCustom]; 45 | thirdbutton.frame = CGRectMake(20, 300, self.view.bounds.size.width - 40, 44); 46 | [thirdbutton setTitle:@"FRDIntent for result" forState:UIControlStateNormal]; 47 | thirdbutton.backgroundColor = [UIColor greenColor]; 48 | [thirdbutton addTarget:self 49 | action:@selector(gotoThirdViewController) 50 | forControlEvents:UIControlEventTouchUpInside]; 51 | [self.view addSubview:thirdbutton]; 52 | 53 | UIButton *fourthbutton = [UIButton buttonWithType:UIButtonTypeCustom]; 54 | fourthbutton.frame = CGRectMake(20, 400, self.view.bounds.size.width - 40, 44); 55 | [fourthbutton setTitle:@"Check intent and dispatch" forState:UIControlStateNormal]; 56 | fourthbutton.backgroundColor = [UIColor greenColor]; 57 | [fourthbutton addTarget:self 58 | action:@selector(gotoCheckAndDispatchViewController) 59 | forControlEvents:UIControlEventTouchUpInside]; 60 | [self.view addSubview:fourthbutton]; 61 | 62 | } 63 | 64 | - (void)gotoFirstViewController 65 | { 66 | NSDictionary *datas = @{@"number": @1, FRDIntentParameters.title: @"First" }; 67 | [self startControllerWithPathIdentifier:@"/user/3001?loc=beijing&uuid=10001#ref" extras:datas]; 68 | } 69 | 70 | - (void)gotoSecondViewController 71 | { 72 | FRDIntent *intent = [[FRDIntent alloc] initWithClazz:[SecondViewController class]]; 73 | [intent putExtraName:@"number" withValue:[NSNumber numberWithInteger:2]]; 74 | [self startControllerWith:intent]; 75 | } 76 | 77 | - (void)gotoThirdViewController 78 | { 79 | NSDictionary *datas = @{@"number": @3, FRDIntentParameters.title: @"Third" }; 80 | 81 | [self startControllerForResultWithPathIdentifier:@"/user/2001/story/1001?loc=beijing&uuid=10001#ref" 82 | extras:datas 83 | requestCode:1]; 84 | } 85 | 86 | - (void)gotoCheckAndDispatchViewController 87 | { 88 | NSDictionary *datas = @{@"number": @4, FRDIntentParameters.title: @"First" }; 89 | [self startControllerWithPathIdentifier:@"/subject/3001?loc=beijing&uuid=10001#ref" extras:datas]; 90 | } 91 | 92 | #pragma mark - FRDIntentForResultSendable 93 | 94 | - (void)controllerDidReturnWithReqeustCode:(NSInteger)requestCode 95 | resultCode:(enum FRDResultCode)code 96 | data:(NSDictionary *)data 97 | { 98 | if (requestCode == 1){ 99 | if (code == FRDResultCodeOk) { 100 | NSString *text = [data objectForKey:@"text"]; 101 | NSLog(@"Successful confirm get from destination : %@", text); 102 | } else if (code == FRDResultCodeCanceled) { 103 | NSString *text = data[@"text"]; 104 | NSLog(@"Canceled confirm get from destination : %@", text); 105 | } 106 | } 107 | } 108 | 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /FRDIntentDemo/SecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import 12 | 13 | @interface SecondViewController : UIViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /FRDIntentDemo/SecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.m 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import "SecondViewController.h" 10 | 11 | @interface SecondViewController () 12 | 13 | @property (nonatomic, strong) NSDictionary *data; 14 | 15 | @end 16 | 17 | @implementation SecondViewController 18 | 19 | - (id)initWithExtras:(NSDictionary *)extras { 20 | self = [super init]; 21 | if (self) { 22 | _data = extras; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | self.title = @"Second View Controller"; 30 | self.view.backgroundColor = [UIColor whiteColor]; 31 | 32 | UILabel *numberLabel = [[UILabel alloc] init]; 33 | numberLabel.frame = CGRectMake(20, 100, self.view.bounds.size.width - 40, 400); 34 | numberLabel.textAlignment = NSTextAlignmentCenter; 35 | numberLabel.numberOfLines = 0; 36 | if (self.data) { 37 | numberLabel.text = [NSString stringWithFormat:@"%@", self.data]; 38 | } 39 | [self.view addSubview:numberLabel]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /FRDIntentDemo/ThirdViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import 12 | 13 | @interface ThirdViewController : UIViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /FRDIntentDemo/ThirdViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.m 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import "ThirdViewController.h" 10 | 11 | @interface ThirdViewController () 12 | 13 | @property (nonatomic, strong) NSDictionary *data; 14 | @property (nonatomic, strong) UITextField *textField; 15 | 16 | @property (nonatomic, assign) NSInteger requestCode; 17 | @property (nonatomic, weak) id delegate; 18 | 19 | 20 | @end 21 | 22 | @implementation ThirdViewController 23 | 24 | - (id)initWithExtras:(NSDictionary *)extras { 25 | self = [super init]; 26 | if (self) { 27 | _data = extras; 28 | [self setupExtras:extras]; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)viewDidLoad { 34 | [super viewDidLoad]; 35 | self.view.backgroundColor = [UIColor whiteColor]; 36 | 37 | UIBarButtonItem *dismiss = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 38 | target:self 39 | action:@selector(dismiss:)]; 40 | self.navigationItem.leftBarButtonItem = dismiss; 41 | 42 | UIBarButtonItem *confirm = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone 43 | target:self 44 | action:@selector(confirm:)]; 45 | 46 | self.navigationItem.rightBarButtonItem = confirm; 47 | 48 | self.textField = [[UITextField alloc] init]; 49 | self.textField.frame = CGRectMake(10, 100, self.view.bounds.size.width - 20, 44); 50 | self.textField.backgroundColor = [UIColor lightGrayColor]; 51 | self.textField.clearButtonMode = UITextFieldViewModeAlways; 52 | self.textField.returnKeyType = UIReturnKeyDone; 53 | self.textField.delegate = self; 54 | [self.view addSubview: self.textField]; 55 | 56 | 57 | UILabel *numberLabel = [[UILabel alloc] init]; 58 | numberLabel.frame = CGRectMake(20, 100, self.view.bounds.size.width - 40, 400); 59 | numberLabel.textAlignment = NSTextAlignmentCenter; 60 | numberLabel.numberOfLines = 0; 61 | if (self.data) { 62 | numberLabel.text = [NSString stringWithFormat:@"%@", self.data]; 63 | } 64 | [self.view addSubview:numberLabel]; 65 | } 66 | 67 | - (void)dismiss:(id)sender { 68 | [self dismissViewControllerAnimated:YES completion:NULL]; 69 | 70 | if (self.delegate) { 71 | NSDictionary *data = @{@"text": self.textField.text ?: @""}; 72 | [self.delegate controllerDidReturnWithReqeustCode:self.requestCode resultCode:FRDResultCodeCanceled data:data]; 73 | } 74 | } 75 | 76 | - (void)confirm:(id)sender { 77 | [self dismissViewControllerAnimated:YES completion:NULL]; 78 | if (self.delegate) { 79 | NSDictionary *data = @{@"text": self.textField.text ?: @""}; 80 | [self.delegate controllerDidReturnWithReqeustCode:self.requestCode resultCode:FRDResultCodeOk data:data]; 81 | } 82 | } 83 | 84 | #pragma mark = IntentForResultReceivable 85 | 86 | - (void)setRequestCode:(NSInteger)requestCode 87 | { 88 | _requestCode = requestCode; 89 | } 90 | 91 | - (void)setDelegate:(__strong id )delegate 92 | { 93 | _delegate = delegate; 94 | } 95 | 96 | #pragma mark - UITextFieldDelegate 97 | 98 | - (BOOL)textFieldShouldReturn:(UITextField *)textField { 99 | [self dismiss:textField]; 100 | return YES; 101 | } 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /FRDIntentDemo/UIViewController+TopViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TopViewController.h 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 03/01/2017. 6 | // Copyright © 2017 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (TopViewController) 12 | 13 | + (UIViewController *)topViewController; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /FRDIntentDemo/UIViewController+TopViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TopViewController.m 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 03/01/2017. 6 | // Copyright © 2017 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+TopViewController.h" 10 | 11 | @implementation UIViewController (TopViewController) 12 | 13 | + (UIViewController *)topViewController 14 | { 15 | return [self _frd_visibleViewControllerFrom:[UIApplication sharedApplication].keyWindow.rootViewController]; 16 | } 17 | 18 | 19 | + (UIViewController *)_frd_visibleViewControllerFrom:(UIViewController *)vc 20 | { 21 | if ([vc isKindOfClass:[UINavigationController class]]) { 22 | return [self _frd_visibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]]; 23 | } 24 | 25 | if ([vc isKindOfClass:[UITabBarController class]]) { 26 | return [self _frd_visibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]]; 27 | } 28 | 29 | if (vc.presentedViewController) { 30 | return [self _frd_visibleViewControllerFrom:vc.presentedViewController]; 31 | } 32 | 33 | return vc; 34 | 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /FRDIntentDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // FRDIntentDemo 4 | // 5 | // Created by GUO Lin on 9/13/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /FRDIntentTests/ControllerManagerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FRDControllerManagerTests.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/30/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import FRDIntent 11 | 12 | class FRDControllerManagerTests: XCTestCase { 13 | 14 | func testNormalSearch() { 15 | 16 | let controllerManager = FRDControllerManager.sharedInstance 17 | controllerManager.register(URL(string: "/user/:userId")!, clazz: MockUserViewController.self) 18 | controllerManager.register(URL(string: "/story/:storyId")!, clazz: MockStoryViewController.self) 19 | controllerManager.register(URL(string: "/user/:userId/profile")!, clazz: MockProfileViewController.self) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /FRDIntentTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /FRDIntentTests/MockViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MockViewController.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/31/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | @testable import FRDIntent 11 | 12 | class MockUserViewController: UIViewController, FRDIntentReceivable { 13 | 14 | required init?(extras: [String: Any]) { 15 | super.init(nibName: nil, bundle: nil) 16 | } 17 | 18 | required init?(coder aDecoder: NSCoder) { 19 | fatalError("init(coder:) has not been implemented") 20 | } 21 | 22 | } 23 | 24 | class MockStoryViewController: UIViewController, FRDIntentReceivable { 25 | 26 | required init?(extras: [String: Any]) { 27 | super.init(nibName: nil, bundle: nil) 28 | } 29 | 30 | required init?(coder aDecoder: NSCoder) { 31 | fatalError("init(coder:) has not been implemented") 32 | } 33 | 34 | } 35 | 36 | class MockProfileViewController: UIViewController, FRDIntentReceivable { 37 | 38 | required init?(extras: [String: Any]) { 39 | super.init(nibName: nil, bundle: nil) 40 | } 41 | 42 | required init?(coder aDecoder: NSCoder) { 43 | fatalError("init(coder:) has not been implemented") 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /FRDIntentTests/RouteManagerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RouteSearchTests.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/30/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import FRDIntent 11 | 12 | class RouteSearch: XCTestCase { 13 | 14 | var routeManager: RouteManager! 15 | 16 | override func setUp() { 17 | super.setUp() 18 | routeManager = RouteManager() 19 | } 20 | 21 | override func tearDown() { 22 | super.tearDown() 23 | routeManager = nil 24 | } 25 | 26 | func testNormalSearch() { 27 | 28 | routeManager.register(URL(string: "/user/:userId")!, clazz: MockUserViewController.self) 29 | routeManager.register(URL(string: "/user/:userId/profile")!, clazz: MockProfileViewController.self) 30 | routeManager.register(URL(string: "/user/:userId/story/:storyId")!, clazz: MockStoryViewController.self) 31 | routeManager.register(URL(string: "/story/:storyId")!, clazz: MockStoryViewController.self) 32 | 33 | let (params, clazz) = routeManager.searchController(with: URL(string: "/user/12")!) 34 | XCTAssert(params["userId"] as! String == "12", "userId is 12") 35 | XCTAssert(clazz == MockUserViewController.self, "mock is user") 36 | 37 | let (params2, value2) = routeManager.searchController(with: URL(string: "/user/123/profile")!) 38 | XCTAssert(params2["userId"] as! String == "123", "userId is 123") 39 | XCTAssert(value2 == MockProfileViewController.self, "value is profile") 40 | 41 | let (params3, value3) = routeManager.searchController(with: URL(string: "/user/123/story/1234")!) 42 | XCTAssert(params3["userId"] as! String == "123", "userId is 123") 43 | XCTAssert(params3["storyId"] as! String == "1234", "storyId is 1234") 44 | XCTAssert(value3 == MockStoryViewController.self, "value is story") 45 | 46 | let (params4, value4) = routeManager.searchController(with: URL(string: "/story/1234/")!) 47 | XCTAssert(params4["storyId"] as! String == "1234", "storyId is 1234") 48 | XCTAssert(value4 == MockStoryViewController.self, "value is story") 49 | 50 | } 51 | 52 | func testNoMatchSearch() { 53 | 54 | let handler1 = {(params: [String: Any]) in 55 | 56 | } 57 | 58 | routeManager.register(URL(string: "/story/:storyId")!, handler: handler1) 59 | routeManager.register(URL(string: "/normal/")!, handler: handler1) 60 | 61 | let (params5, value5) = routeManager.searchHandler(with: URL(string: "/story/12345/error")!) 62 | XCTAssert(value5 != nil, "value is not nil") 63 | XCTAssert(params5["storyId"] as! String == "12345", "storyId is 1234") 64 | 65 | let (params6, value6) = routeManager.searchHandler(with: URL(string: "/error")!) 66 | XCTAssert(params6[FRDIntentParameters.URL] as? URL == URL(string: "/error"), "") 67 | XCTAssert(value6 == nil, "no match, value is nil") 68 | 69 | routeManager.register(URL(string: "/intent/paying")!, handler: handler1) 70 | 71 | let (params, value) = routeManager.searchHandler(with: URL(string: "/intent/profile")!) 72 | let url = params["URLRouteURL"] as! URL 73 | XCTAssert(url.absoluteString == "/intent/profile", "parent is return") 74 | XCTAssert(value == nil, "no match, value is nil") 75 | } 76 | 77 | func testNearestNoMatchSearch() { 78 | let handler1 = {(params: [String: Any]) in 79 | 80 | } 81 | 82 | routeManager.register(URL(string: "/intent/paying")!, handler: handler1) 83 | routeManager.register(URL(string: "/intent")!, handler: handler1) 84 | 85 | let (params, value) = routeManager.searchHandler(with: URL(string: "/intent/profile")!) 86 | let url = params["URLRouteURL"] as! URL 87 | XCTAssert(url.absoluteString == "/intent/profile", "parent is return") 88 | XCTAssert(value != nil, "match parent /intent, value is not nil") 89 | } 90 | 91 | func testQueryFragmentParameter() { 92 | 93 | routeManager.register(URL(string: "/paramss")!, clazz: MockStoryViewController.self) 94 | 95 | let (params7, value7) = routeManager.searchController(with: URL(string: "/paramss?key1=value1&key2=value2#ref")!) 96 | XCTAssert(params7["key1"] as! String == "value1", "params key1 is value1") 97 | XCTAssert(params7["key2"] as! String == "value2", "params key2 is value2") 98 | XCTAssert(params7["fragment"] as! String == "ref", "params fragment is ref") 99 | XCTAssert(value7 == MockStoryViewController.self, "value is nil") 100 | } 101 | 102 | func testRemoveURL() { 103 | let url = URL(string: "/param/to/:be/remove/:id")! 104 | routeManager.register(url, clazz: MockStoryViewController.self) 105 | let (_, value) = routeManager.searchController(with: url) 106 | XCTAssert(value != nil) 107 | routeManager.unregisterController(with: url) 108 | let (_, value2) = routeManager.searchController(with: url) 109 | XCTAssert(value2 == nil) 110 | } 111 | 112 | func testRemoveSamilarURL() { 113 | let url = URL(string: "/a/b")! 114 | routeManager.register(url, clazz: MockStoryViewController.self) 115 | let url2 = URL(string: "a/c")! 116 | routeManager.register(url2, clazz: MockStoryViewController.self) 117 | routeManager.unregisterController(with: url) 118 | let (_, value2) = routeManager.searchController(with: url2) 119 | XCTAssert(value2 != nil) 120 | } 121 | 122 | func testConflictWithPlaceholder() { 123 | 124 | let handler : URLRoutesHandler = { params in 125 | print("url: \(params[FRDIntentParameters.URL] as! String)") 126 | } 127 | 128 | let url = URL(string: "user/:id/reviews")! 129 | routeManager.register(url, clazz: MockUserViewController.self) 130 | 131 | let url2 = URL(string: "user/profile/reviews")! 132 | routeManager.register(url2, handler: handler) 133 | 134 | let (_, value2) = routeManager.searchHandler(with: url2) 135 | XCTAssert(value2 != nil) 136 | } 137 | 138 | func testInsertPlaceholder() { 139 | 140 | let url = URL(string: "user/:id/reviews")! 141 | let result1 = routeManager.register(url, clazz: MockUserViewController.self) 142 | XCTAssert(result1) 143 | 144 | let url2 = URL(string: "user/:number/reviews")! 145 | let result2 = routeManager.register(url2, clazz: MockStoryViewController.self) 146 | XCTAssert(result2 != true) 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /FRDIntentTests/URLRoutesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // URLRoutesTests.swift 3 | // FRDIntent 4 | // 5 | // Created by GUO Lin on 8/31/16. 6 | // Copyright © 2016 Douban Inc. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import FRDIntent 11 | 12 | class URLRoutesTests: XCTestCase { 13 | 14 | func testURLRoutes() { 15 | let router = FRDURLRoutes.sharedInstance 16 | 17 | router.register(URL(string: "/user/:userId")!) { (params: [String: Any]) in 18 | XCTAssert(params["userId"] as! String == "12", "userId is 12") 19 | XCTAssert(params[FRDIntentParameters.URL] as? NSURL == NSURL(string: "/user/12"), "") 20 | } 21 | 22 | _ = router.route(URL(string: "/user/12")!) 23 | 24 | router.register(URL(string: "/story/:storyId")!) { (params: [String: Any]) in 25 | XCTAssert(params["storyId"] as! String == "21", "userId is 12") 26 | XCTAssert(params["key1"] as! String == "value1", "key1 is value1") 27 | XCTAssert(params["key2"] as! String == "value2", "key2 is value2") 28 | XCTAssert(params["fragment"] as! String == "ref", "fragment is ref") 29 | } 30 | _ = router.route(URL(string: "/story/21/?key1=value1&key2=value2#ref")!) 31 | 32 | } 33 | 34 | func testNearestNoMatch() { 35 | 36 | let router = FRDURLRoutes.sharedInstance 37 | 38 | router.register(URL(string: "/a/b/c/e")!) { (params: [String: Any]) in 39 | XCTAssert(params[FRDIntentParameters.URL] as? NSURL == NSURL(string: "/a/b/c/e"), "") 40 | } 41 | 42 | router.register(URL(string: "/a/b")!) { (params: [String: Any]) in 43 | XCTAssert(params[FRDIntentParameters.URL] as? NSURL == NSURL(string: "/a/b/c"), "") 44 | } 45 | 46 | let result = router.route(URL(string: "/a/b/c")!) 47 | XCTAssert(result, "can rout") 48 | } 49 | 50 | 51 | func testPlaceholder() { 52 | 53 | let router = FRDURLRoutes.sharedInstance 54 | 55 | router.register(URL(string: "/a/x/c/d/e")!) { (params: [String: Any]) in 56 | XCTAssert(false) 57 | } 58 | 59 | router.register(URL(string: "/a/:b/c/d")!) { (params: [String: Any]) in 60 | XCTAssert(true) 61 | } 62 | 63 | router.register(URL(string: "/a/x/c")!) { (params: [String: Any]) in 64 | XCTAssert(false) 65 | } 66 | 67 | 68 | let result = router.route(URL(string: "/a/x/c/d")!) 69 | XCTAssert(result, "/a/x/c can route by pattern /a/:b/c") 70 | } 71 | 72 | 73 | 74 | func testCanRoute() { 75 | let router = FRDURLRoutes.sharedInstance 76 | 77 | router.register(URL(string: "/aaa/ddd")!) { (params) in 78 | 79 | } 80 | XCTAssert(router.canRoute(URL(string: "/aaa/ddd")!)) 81 | XCTAssertFalse(router.canRoute(URL(string: "/aaa/dddd")!)) 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | **Copyright (c) 2016, Douban. Inc.** 2 | **All rights reserved.** 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | the Software, and to permit persons to whom the Software is furnished to do so, 9 | subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | INCLUDINGMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /docs/Classes/FRDRouteParameters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FRDRouteParameters Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (98% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 91 |
92 |
93 |
94 |

FRDRouteParameters

95 |
96 |
97 |
public class FRDRouteParameters: NSObject
98 | 99 |
100 |
101 |

Open the parameters to public. 102 | Defined as a class because of the usage of Objective-C.

103 | 104 |
105 |
106 |
107 |
    108 |
  • 109 |
    110 | 111 | 112 | 113 | URLRouteURL 114 | 115 |
    116 |
    117 |
    118 |
    119 |
    120 |
    121 |

    The key to get the url from parameters of block handler.

    122 | 123 |
    124 |
    125 |

    Declaration

    126 |
    127 |

    Swift

    128 |
    public static let URLRouteURL = "URLRouteURL"
    129 | 130 |
    131 |
    132 |
    133 |
    134 |
  • 135 |
136 |
137 |
138 |
139 | 143 |
144 |
145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/Classes/PresentationDisplay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PresentationDisplay Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

PresentationDisplay

81 |
82 |
83 |
public class PresentationDisplay: ControllerDisplay
84 | 85 |
86 |
87 |

The way of display view controllers with present. It calls presentViewController(viewController: UIViewController, animated: Bool)

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | displayViewController(source:destination:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    How to display the destination view controller.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    public func displayViewController<T: UIViewController>(source source: T, destination: T)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 | 140 | 146 | 147 | 148 |
    123 | 124 | source 125 | 126 | 128 |
    129 |

    The source view controller.

    130 | 131 |
    132 |
    136 | 137 | destination 138 | 139 | 141 |
    142 |

    The destination view controller.

    143 | 144 |
    145 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
157 | 161 |
162 |
163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/Classes/PushDisplay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PushDisplay Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

PushDisplay

81 |
82 |
83 |
public class PushDisplay: ControllerDisplay
84 | 85 |
86 |
87 |

The way of display view controllers with push. It calls pushViewController(viewController: UIViewController, animated: Bool)

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | displayViewController(source:destination:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    How to display the destination view controller.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    public func displayViewController<T: UIViewController>(source source: T, destination: T)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 | 140 | 146 | 147 | 148 |
    123 | 124 | source 125 | 126 | 128 |
    129 |

    The source view controller.

    130 | 131 |
    132 |
    136 | 137 | destination 138 | 139 | 141 |
    142 |

    The destination view controller.

    143 | 144 |
    145 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
157 | 161 |
162 |
163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enums Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

FRDIntent Docs (98% documented)

17 |
18 |
19 |
20 | 25 |
26 |
27 | 90 |
91 |
92 |
93 |

Enums

94 |

The following enums are available globally.

95 | 96 |
97 |
98 |
99 |
    100 |
  • 101 |
    102 | 103 | 104 | 105 | FRDResultCode 106 | 107 |
    108 |
    109 |
    110 |
    111 |
    112 |
    113 |

    The resultCode’s possible values:

    114 | 115 | See more 116 |
    117 |
    118 |

    Declaration

    119 |
    120 |

    Swift

    121 |
    @objc public enum FRDResultCode: Int
    122 | 123 |
    124 |
    125 |
    126 |
    127 |
  • 128 |
129 |
130 |
131 |
132 | 136 |
137 |
138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /docs/Extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extensions Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

FRDIntent Docs (98% documented)

17 |
18 |
19 |
20 | 25 |
26 |
27 | 90 |
91 |
92 |
93 |

Extensions

94 |

The following extensions are available globally.

95 | 96 |
97 |
98 |
99 |
    100 |
  • 101 |
    102 | 103 | 104 | 105 | UIViewController 106 | 107 |
    108 |
    109 |
    110 |
    111 |
    112 |
    113 |

    Undocumented

    114 | 115 | See more 116 |
    117 |
    118 |
    119 |
  • 120 |
121 |
122 |
123 |
124 | 128 |
129 |
130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/Protocols/ControllerDisplay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControllerDisplay Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

ControllerDisplay

81 |
82 |
83 |
public protocol ControllerDisplay
84 | 85 |
86 |
87 |

The protocol for abstract the way of how display the destination view controller.

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | displayViewController(source:destination:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    How to display the destination view controller.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    func displayViewController<T: UIViewController>(source source: T, destination: T)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 | 140 | 146 | 147 | 148 |
    123 | 124 | source 125 | 126 | 128 |
    129 |

    The source view controller.

    130 | 131 |
    132 |
    136 | 137 | destination 138 | 139 | 141 |
    142 |

    The destination view controller.

    143 | 144 |
    145 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
157 | 161 |
162 |
163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/Protocols/IntentForResultReceivable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IntentForResultReceivable Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

IntentForResultReceivable

81 |
82 |
83 |
public protocol IntentForResultReceivable: IntentReceivable
84 | 85 |
86 |
87 |

The protocol to abstract the view controller tha can receive the Intent for request a result from the destination.

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | requestCode 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    The integer request code originally supplied to startControllerForResult(), allowing you to identify who this result came from.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    var requestCode: Int?
    114 | 115 |
    116 |
    117 |
    118 |
    119 |
  • 120 |
  • 121 |
    122 | 123 | 124 | 125 | delegate 126 | 127 |
    128 |
    129 |
    130 |
    131 |
    132 |
    133 |

    The source view controller

    134 | 135 |
    136 |
    137 |

    Declaration

    138 |
    139 |

    Swift

    140 |
    var delegate: IntentForResultSendable?
    141 | 142 |
    143 |
    144 |
    145 |
    146 |
  • 147 |
148 |
149 |
150 |
151 | 155 |
156 |
157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /docs/Protocols/IntentReceivable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IntentReceivable Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

IntentReceivable

81 |
82 |
83 |
public protocol IntentReceivable
84 | 85 |
86 |
87 |

The protocol to abstract the view controller tha can receive the Intent.

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | init(extras:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    Initialzier with extra data.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    init(extras: Dictionary<String, Any>?)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 |
    123 | 124 | extras 125 | 126 | 128 |
    129 |

    The extra data.

    130 | 131 |
    132 |
    136 |
    137 |
    138 |
    139 |
  • 140 |
141 |
142 |
143 |
144 | 148 |
149 |
150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | 168 | .section { 169 | padding: 0 25px; } 170 | 171 | .highlight { 172 | background-color: #eee; 173 | padding: 10px 12px; 174 | border: 1px solid #e2e2e2; 175 | border-radius: 4px; 176 | overflow-x: auto; } 177 | 178 | .declaration .highlight { 179 | overflow-x: initial; 180 | padding: 0 40px 40px 0; 181 | margin-bottom: -25px; 182 | background-color: transparent; 183 | border: none; } 184 | 185 | .section-name { 186 | margin: 0; 187 | margin-left: 18px; } 188 | 189 | .task-group-section { 190 | padding-left: 6px; 191 | border-top: 1px solid #e2e2e2; } 192 | 193 | .task-group { 194 | padding-top: 0px; } 195 | 196 | .task-name-container a[name]:before { 197 | content: ""; 198 | display: block; 199 | padding-top: 70px; 200 | margin: -70px 0 0; } 201 | 202 | .item { 203 | padding-top: 8px; 204 | width: 100%; 205 | list-style-type: none; } 206 | .item a[name]:before { 207 | content: ""; 208 | display: block; 209 | padding-top: 70px; 210 | margin: -70px 0 0; } 211 | .item code { 212 | background-color: transparent; 213 | padding: 0; } 214 | .item .token { 215 | padding-left: 3px; 216 | margin-left: 15px; 217 | font-size: 11.9px; } 218 | .item .declaration-note { 219 | font-size: .85em; 220 | color: gray; 221 | font-style: italic; } 222 | 223 | .pointer-container { 224 | border-bottom: 1px solid #e2e2e2; 225 | left: -23px; 226 | padding-bottom: 13px; 227 | position: relative; 228 | width: 110%; } 229 | 230 | .pointer { 231 | background: #f9f9f9; 232 | border-left: 1px solid #e2e2e2; 233 | border-top: 1px solid #e2e2e2; 234 | height: 12px; 235 | left: 21px; 236 | top: -7px; 237 | -webkit-transform: rotate(45deg); 238 | -moz-transform: rotate(45deg); 239 | -o-transform: rotate(45deg); 240 | transform: rotate(45deg); 241 | position: absolute; 242 | width: 12px; } 243 | 244 | .height-container { 245 | display: none; 246 | left: -25px; 247 | padding: 0 25px; 248 | position: relative; 249 | width: 100%; 250 | overflow: hidden; } 251 | .height-container .section { 252 | background: #f9f9f9; 253 | border-bottom: 1px solid #e2e2e2; 254 | left: -25px; 255 | position: relative; 256 | width: 100%; 257 | padding-top: 10px; 258 | padding-bottom: 5px; } 259 | 260 | .aside, .language { 261 | padding: 6px 12px; 262 | margin: 12px 0; 263 | border-left: 5px solid #dddddd; 264 | overflow-y: hidden; } 265 | .aside .aside-title, .language .aside-title { 266 | font-size: 9px; 267 | letter-spacing: 2px; 268 | text-transform: uppercase; 269 | padding-bottom: 0; 270 | margin: 0; 271 | color: #aaa; 272 | -webkit-user-select: none; } 273 | .aside p:last-child, .language p:last-child { 274 | margin-bottom: 0; } 275 | 276 | .language { 277 | border-left: 5px solid #cde9f4; } 278 | .language .aside-title { 279 | color: #4b8afb; } 280 | 281 | .aside-warning { 282 | border-left: 5px solid #ff6666; } 283 | .aside-warning .aside-title { 284 | color: #ff0000; } 285 | 286 | .graybox { 287 | border-collapse: collapse; 288 | width: 100%; } 289 | .graybox p { 290 | margin: 0; 291 | word-break: break-word; 292 | min-width: 50px; } 293 | .graybox td { 294 | border: 1px solid #e2e2e2; 295 | padding: 5px 25px 5px 10px; 296 | vertical-align: middle; } 297 | .graybox tr td:first-of-type { 298 | text-align: right; 299 | padding: 7px; 300 | vertical-align: top; 301 | word-break: normal; 302 | width: 40px; } 303 | 304 | .slightly-smaller { 305 | font-size: 0.9em; } 306 | 307 | #footer { 308 | position: absolute; 309 | bottom: 10px; 310 | margin-left: 25px; } 311 | #footer p { 312 | margin: 0; 313 | color: #aaa; 314 | font-size: 0.8em; } 315 | 316 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 317 | display: none; } 318 | html.dash .main-content { 319 | width: 980px; 320 | margin-left: 0; 321 | border: none; 322 | width: 100%; 323 | top: 0; 324 | padding-bottom: 0; } 325 | html.dash .height-container { 326 | display: block; } 327 | html.dash .item .token { 328 | margin-left: 0; } 329 | html.dash .content-wrapper { 330 | width: auto; } 331 | html.dash #footer { 332 | position: static; } 333 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.frdintent 7 | CFBundleName 8 | FRDIntent 9 | DocSetPlatformFamily 10 | frdintent 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Classes/FRDRouteParameters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FRDRouteParameters Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (98% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 91 |
92 |
93 |
94 |

FRDRouteParameters

95 |
96 |
97 |
public class FRDRouteParameters: NSObject
98 | 99 |
100 |
101 |

Open the parameters to public. 102 | Defined as a class because of the usage of Objective-C.

103 | 104 |
105 |
106 |
107 |
    108 |
  • 109 |
    110 | 111 | 112 | 113 | URLRouteURL 114 | 115 |
    116 |
    117 |
    118 |
    119 |
    120 |
    121 |

    The key to get the url from parameters of block handler.

    122 | 123 |
    124 |
    125 |

    Declaration

    126 |
    127 |

    Swift

    128 |
    public static let URLRouteURL = "URLRouteURL"
    129 | 130 |
    131 |
    132 |
    133 |
    134 |
  • 135 |
136 |
137 |
138 |
139 | 143 |
144 |
145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Classes/PresentationDisplay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PresentationDisplay Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

PresentationDisplay

81 |
82 |
83 |
public class PresentationDisplay: ControllerDisplay
84 | 85 |
86 |
87 |

The way of display view controllers with present. It calls presentViewController(viewController: UIViewController, animated: Bool)

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | displayViewController(source:destination:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    How to display the destination view controller.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    public func displayViewController<T: UIViewController>(source source: T, destination: T)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 | 140 | 146 | 147 | 148 |
    123 | 124 | source 125 | 126 | 128 |
    129 |

    The source view controller.

    130 | 131 |
    132 |
    136 | 137 | destination 138 | 139 | 141 |
    142 |

    The destination view controller.

    143 | 144 |
    145 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
157 | 161 |
162 |
163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Classes/PushDisplay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PushDisplay Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

PushDisplay

81 |
82 |
83 |
public class PushDisplay: ControllerDisplay
84 | 85 |
86 |
87 |

The way of display view controllers with push. It calls pushViewController(viewController: UIViewController, animated: Bool)

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | displayViewController(source:destination:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    How to display the destination view controller.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    public func displayViewController<T: UIViewController>(source source: T, destination: T)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 | 140 | 146 | 147 | 148 |
    123 | 124 | source 125 | 126 | 128 |
    129 |

    The source view controller.

    130 | 131 |
    132 |
    136 | 137 | destination 138 | 139 | 141 |
    142 |

    The destination view controller.

    143 | 144 |
    145 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
157 | 161 |
162 |
163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enums Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

FRDIntent Docs (98% documented)

17 |
18 |
19 |
20 | 25 |
26 |
27 | 90 |
91 |
92 |
93 |

Enums

94 |

The following enums are available globally.

95 | 96 |
97 |
98 |
99 |
    100 |
  • 101 |
    102 | 103 | 104 | 105 | FRDResultCode 106 | 107 |
    108 |
    109 |
    110 |
    111 |
    112 |
    113 |

    The resultCode’s possible values:

    114 | 115 | See more 116 |
    117 |
    118 |

    Declaration

    119 |
    120 |

    Swift

    121 |
    @objc public enum FRDResultCode: Int
    122 | 123 |
    124 |
    125 |
    126 |
    127 |
  • 128 |
129 |
130 |
131 |
132 | 136 |
137 |
138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extensions Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

FRDIntent Docs (98% documented)

17 |
18 |
19 |
20 | 25 |
26 |
27 | 90 |
91 |
92 |
93 |

Extensions

94 |

The following extensions are available globally.

95 | 96 |
97 |
98 |
99 |
    100 |
  • 101 |
    102 | 103 | 104 | 105 | UIViewController 106 | 107 |
    108 |
    109 |
    110 |
    111 |
    112 |
    113 |

    Undocumented

    114 | 115 | See more 116 |
    117 |
    118 |
    119 |
  • 120 |
121 |
122 |
123 |
124 | 128 |
129 |
130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Protocols/ControllerDisplay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ControllerDisplay Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

ControllerDisplay

81 |
82 |
83 |
public protocol ControllerDisplay
84 | 85 |
86 |
87 |

The protocol for abstract the way of how display the destination view controller.

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | displayViewController(source:destination:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    How to display the destination view controller.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    func displayViewController<T: UIViewController>(source source: T, destination: T)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 | 140 | 146 | 147 | 148 |
    123 | 124 | source 125 | 126 | 128 |
    129 |

    The source view controller.

    130 | 131 |
    132 |
    136 | 137 | destination 138 | 139 | 141 |
    142 |

    The destination view controller.

    143 | 144 |
    145 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
157 | 161 |
162 |
163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Protocols/IntentForResultReceivable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IntentForResultReceivable Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

IntentForResultReceivable

81 |
82 |
83 |
public protocol IntentForResultReceivable: IntentReceivable
84 | 85 |
86 |
87 |

The protocol to abstract the view controller tha can receive the Intent for request a result from the destination.

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | requestCode 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    The integer request code originally supplied to startControllerForResult(), allowing you to identify who this result came from.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    var requestCode: Int?
    114 | 115 |
    116 |
    117 |
    118 |
    119 |
  • 120 |
  • 121 |
    122 | 123 | 124 | 125 | delegate 126 | 127 |
    128 |
    129 |
    130 |
    131 |
    132 |
    133 |

    The source view controller

    134 | 135 |
    136 |
    137 |

    Declaration

    138 |
    139 |

    Swift

    140 |
    var delegate: IntentForResultSendable?
    141 | 142 |
    143 |
    144 |
    145 |
    146 |
  • 147 |
148 |
149 |
150 |
151 | 155 |
156 |
157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/Protocols/IntentReceivable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IntentReceivable Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

FRDIntent Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 77 |
78 |
79 |
80 |

IntentReceivable

81 |
82 |
83 |
public protocol IntentReceivable
84 | 85 |
86 |
87 |

The protocol to abstract the view controller tha can receive the Intent.

88 | 89 |
90 |
91 |
92 |
    93 |
  • 94 |
    95 | 96 | 97 | 98 | init(extras:) 99 | 100 |
    101 |
    102 |
    103 |
    104 |
    105 |
    106 |

    Initialzier with extra data.

    107 | 108 |
    109 |
    110 |

    Declaration

    111 |
    112 |

    Swift

    113 |
    init(extras: Dictionary<String, Any>?)
    114 | 115 |
    116 |
    117 |
    118 |

    Parameters

    119 | 120 | 121 | 122 | 127 | 133 | 134 | 135 |
    123 | 124 | extras 125 | 126 | 128 |
    129 |

    The extra data.

    130 | 131 |
    132 |
    136 |
    137 |
    138 |
    139 |
  • 140 |
141 |
142 |
143 |
144 | 148 |
149 |
150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | 168 | .section { 169 | padding: 0 25px; } 170 | 171 | .highlight { 172 | background-color: #eee; 173 | padding: 10px 12px; 174 | border: 1px solid #e2e2e2; 175 | border-radius: 4px; 176 | overflow-x: auto; } 177 | 178 | .declaration .highlight { 179 | overflow-x: initial; 180 | padding: 0 40px 40px 0; 181 | margin-bottom: -25px; 182 | background-color: transparent; 183 | border: none; } 184 | 185 | .section-name { 186 | margin: 0; 187 | margin-left: 18px; } 188 | 189 | .task-group-section { 190 | padding-left: 6px; 191 | border-top: 1px solid #e2e2e2; } 192 | 193 | .task-group { 194 | padding-top: 0px; } 195 | 196 | .task-name-container a[name]:before { 197 | content: ""; 198 | display: block; 199 | padding-top: 70px; 200 | margin: -70px 0 0; } 201 | 202 | .item { 203 | padding-top: 8px; 204 | width: 100%; 205 | list-style-type: none; } 206 | .item a[name]:before { 207 | content: ""; 208 | display: block; 209 | padding-top: 70px; 210 | margin: -70px 0 0; } 211 | .item code { 212 | background-color: transparent; 213 | padding: 0; } 214 | .item .token { 215 | padding-left: 3px; 216 | margin-left: 15px; 217 | font-size: 11.9px; } 218 | .item .declaration-note { 219 | font-size: .85em; 220 | color: gray; 221 | font-style: italic; } 222 | 223 | .pointer-container { 224 | border-bottom: 1px solid #e2e2e2; 225 | left: -23px; 226 | padding-bottom: 13px; 227 | position: relative; 228 | width: 110%; } 229 | 230 | .pointer { 231 | background: #f9f9f9; 232 | border-left: 1px solid #e2e2e2; 233 | border-top: 1px solid #e2e2e2; 234 | height: 12px; 235 | left: 21px; 236 | top: -7px; 237 | -webkit-transform: rotate(45deg); 238 | -moz-transform: rotate(45deg); 239 | -o-transform: rotate(45deg); 240 | transform: rotate(45deg); 241 | position: absolute; 242 | width: 12px; } 243 | 244 | .height-container { 245 | display: none; 246 | left: -25px; 247 | padding: 0 25px; 248 | position: relative; 249 | width: 100%; 250 | overflow: hidden; } 251 | .height-container .section { 252 | background: #f9f9f9; 253 | border-bottom: 1px solid #e2e2e2; 254 | left: -25px; 255 | position: relative; 256 | width: 100%; 257 | padding-top: 10px; 258 | padding-bottom: 5px; } 259 | 260 | .aside, .language { 261 | padding: 6px 12px; 262 | margin: 12px 0; 263 | border-left: 5px solid #dddddd; 264 | overflow-y: hidden; } 265 | .aside .aside-title, .language .aside-title { 266 | font-size: 9px; 267 | letter-spacing: 2px; 268 | text-transform: uppercase; 269 | padding-bottom: 0; 270 | margin: 0; 271 | color: #aaa; 272 | -webkit-user-select: none; } 273 | .aside p:last-child, .language p:last-child { 274 | margin-bottom: 0; } 275 | 276 | .language { 277 | border-left: 5px solid #cde9f4; } 278 | .language .aside-title { 279 | color: #4b8afb; } 280 | 281 | .aside-warning { 282 | border-left: 5px solid #ff6666; } 283 | .aside-warning .aside-title { 284 | color: #ff0000; } 285 | 286 | .graybox { 287 | border-collapse: collapse; 288 | width: 100%; } 289 | .graybox p { 290 | margin: 0; 291 | word-break: break-word; 292 | min-width: 50px; } 293 | .graybox td { 294 | border: 1px solid #e2e2e2; 295 | padding: 5px 25px 5px 10px; 296 | vertical-align: middle; } 297 | .graybox tr td:first-of-type { 298 | text-align: right; 299 | padding: 7px; 300 | vertical-align: top; 301 | word-break: normal; 302 | width: 40px; } 303 | 304 | .slightly-smaller { 305 | font-size: 0.9em; } 306 | 307 | #footer { 308 | position: absolute; 309 | bottom: 10px; 310 | margin-left: 25px; } 311 | #footer p { 312 | margin: 0; 313 | color: #aaa; 314 | font-size: 0.8em; } 315 | 316 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 317 | display: none; } 318 | html.dash .main-content { 319 | width: 980px; 320 | margin-left: 0; 321 | border: none; 322 | width: 100%; 323 | top: 0; 324 | padding-bottom: 0; } 325 | html.dash .height-container { 326 | display: block; } 327 | html.dash .item .token { 328 | margin-left: 0; } 329 | html.dash .content-wrapper { 330 | width: auto; } 331 | html.dash #footer { 332 | position: static; } 333 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/docsets/FRDIntent.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/docsets/FRDIntent.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/docsets/FRDIntent.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/Documents/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | { 4 | "file": "/Users/guolin/db/FRDIntent/FRDIntent/Source/Intent/FRDIntentParameters.swift", 5 | "line": 19, 6 | "symbol": "FRDIntentParameters.hidesBottomBarWhenPushed", 7 | "symbol_kind": "source.lang.swift.decl.var.static", 8 | "warning": "undocumented" 9 | } 10 | ], 11 | "source_directory": "/Users/guolin/db/FRDIntent" 12 | } -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/docsets/FRDIntent.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/FRDIntent.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/docsets/FRDIntent.tgz -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/img/dash.png -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/douban/FRDIntent/9fa5a67089aaf77d8a1776e6361bbc89015d35cd/docs/img/gh.png -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | -------------------------------------------------------------------------------- /docs/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | { 4 | "file": "/Users/guolin/db/FRDIntent/FRDIntent/Source/Intent/FRDIntentParameters.swift", 5 | "line": 19, 6 | "symbol": "FRDIntentParameters.hidesBottomBarWhenPushed", 7 | "symbol_kind": "source.lang.swift.decl.var.static", 8 | "warning": "undocumented" 9 | } 10 | ], 11 | "source_directory": "/Users/guolin/db/FRDIntent" 12 | } -------------------------------------------------------------------------------- /install_swiftlint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Installs the SwiftLint package. 4 | # Tries to get the precompiled .pkg file from Github, but if that 5 | # fails just recompiles from source. 6 | 7 | set -e 8 | 9 | SWIFTLINT_PKG_PATH="/tmp/SwiftLint.pkg" 10 | SWIFTLINT_PKG_URL="https://github.com/realm/SwiftLint/releases/download/0.23.1/SwiftLint.pkg" 11 | 12 | wget --output-document=$SWIFTLINT_PKG_PATH $SWIFTLINT_PKG_URL 13 | 14 | if [ -f $SWIFTLINT_PKG_PATH ]; then 15 | echo "SwiftLint package exists! Installing it..." 16 | sudo installer -pkg $SWIFTLINT_PKG_PATH -target / 17 | else 18 | echo "SwiftLint package doesn't exist. Compiling from source..." && 19 | git clone https://github.com/realm/SwiftLint.git /tmp/SwiftLint && 20 | cd /tmp/SwiftLint && 21 | git submodule update --init --recursive && 22 | sudo make install 23 | fi --------------------------------------------------------------------------------