diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..ba0223c --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,3 @@ +coverage: + ignore: + - Example/.* diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..7668302 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,25 @@ +### Description + +> Describe the issue you are seeing. + +### Steps to Reproduce + +1. +2. +3. + +### Expected Result + +### Actual Result + +### Version Information + +The current version I am using is: + +- Xcode: +- iOS: +- BaseViewControllerSwift: + +### Other Information + +> Add logs, screenshots, etc. that will help in debugging the issue. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..c9f71d8 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +### Summary + +> Provide a general description of what is this Pull Request about and any +context that makes easier to review the changes. + +> If it addresses a Github Issue please mention the number (e.g. `#34`) to keep +track of the different parts of the topic. diff --git a/.gitignore b/.gitignore index 8615121..2c22487 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,12 @@ # Xcode # +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated build/ +DerivedData/ + +## Various settings *.pbxuser !default.pbxuser *.mode1v3 @@ -9,19 +15,33 @@ build/ !default.mode2v3 *.perspectivev3 !default.perspectivev3 -xcuserdata -*.xccheckout +xcuserdata/ + +## Other *.moved-aside -DerivedData +*.xcuserstate + +## Obj-C/Swift specific *.hmap *.ipa -*.xcuserstate +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: -# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # # Pods/ @@ -31,3 +51,15 @@ DerivedData # Carthage/Checkouts Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000..f398a20 --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +3.0 \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..c284b39 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,25 @@ +disabled_rules: # rule identifiers to exclude from running + - function_body_length + - line_length + - nesting + - operator_whitespace + - trailing_whitespace + - type_body_length + - variable_name +excluded: # paths to ignore during linting. overridden by `included`. + - Pods + - 'Wayfindr EustonTests' +# parameterized rules can be customized from this configuration file +line_length: 110 +# parameterized rules are first parameterized as a warning level, then error level. +type_body_length: + - 300 # warning + - 400 # error +# parameterized rules are first parameterized as a warning level, then error level. +variable_name_max_length: + - 40 # warning + - 60 # error +# parameterized rules are first parameterized as a warning level, then error level. +variable_name_min_length: + - 3 # warning + - 2 # error diff --git a/.travis.yml b/.travis.yml index 8d86780..a39d9ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,35 +1,14 @@ +osx_image: xcode8 language: objective-c -osx_image: xcode7.2 + env: global: - LC_CTYPE=en_US.UTF-8 - LANG=en_US.UTF-8 - - WORKSPACE=BaseViewControllerSwift.xcworkspace - - IOS_FRAMEWORK_SCHEME="BaseViewControllerSwift iOS" - - IOS_SDK=iphonesimulator9.2 - - OSX_SDK=macosx10.11 - - TVOS_SDK=appletvsimulator9.1 - - WATCHOS_SDK=watchsimulator2.1 - - EXAMPLE_SCHEME="iOS Example" - matrix: - - DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" - - DESTINATION="OS=9.2,name=iPhone 6S Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="YES" -script: - - set -o pipefail - - xcodebuild -version - - xcodebuild -showsdks - # Build Framework in Debug and Run Tests if specified - - if [ $RUN_TESTS == "YES" ]; then - xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=YES test | xcpretty -c; - else - xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; - fi - - # Build Example in Debug if specified - - if [ $BUILD_EXAMPLE == "YES" ]; then - xcodebuild -workspace "$WORKSPACE" -scheme "$EXAMPLE_SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; - fi +# Test using Fastlane +script: + - ./fastlane/travis.sh after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/BaseViewControllerSwift.podspec b/BaseViewControllerSwift.podspec index 2708c1d..7b3d367 100644 --- a/BaseViewControllerSwift.podspec +++ b/BaseViewControllerSwift.podspec @@ -1,17 +1,18 @@ Pod::Spec.new do |s| s.name = 'BaseViewControllerSwift' - s.version = '1.0.0' + s.version = '2.0.0' s.license = 'MIT' s.summary = 'An organizational tool for writing custom view controllers using UIKit.' s.homepage = 'https://github.com/ustwo/baseviewcontroller-swift' s.authors = { 'Shagun Madhikarmi' => 'shagun@ustwo.com', - 'Aaron McTavish' => 'aamct@ustwo.com', - 'Martin Stolz' => 'martin@ustwo.com' } + 'Aaron McTavish' => 'aamct@ustwo.com' } s.source = { :git => 'https://github.com/ustwo/baseviewcontroller-swift.git', :tag => s.version } s.ios.deployment_target = '8.3' s.source_files = 'Sources/*.swift' + s.frameworks = 'Foundation', 'UIKit' + s.requires_arc = true end diff --git a/BaseViewControllerSwift.xcodeproj/project.pbxproj b/BaseViewControllerSwift.xcodeproj/project.pbxproj index d14f050..a81947a 100644 --- a/BaseViewControllerSwift.xcodeproj/project.pbxproj +++ b/BaseViewControllerSwift.xcodeproj/project.pbxproj @@ -122,6 +122,7 @@ 005153461C3D148D00C8533E /* Frameworks */, 005153471C3D148D00C8533E /* Headers */, 005153481C3D148D00C8533E /* Resources */, + 006F491D1DB5052000C8F4FC /* ShellScript */, ); buildRules = ( ); @@ -157,14 +158,16 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = BaseViewControllerSwift; TargetAttributes = { 005153491C3D148D00C8533E = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; 005153531C3D148D00C8533E = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; }; }; @@ -203,6 +206,22 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 006F491D1DB5052000C8F4FC /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"SwiftLint does not exist, download from https://github.com/realm/SwiftLint\"\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 005153451C3D148D00C8533E /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -245,8 +264,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -274,6 +295,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -293,8 +315,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -314,6 +338,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -325,6 +351,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -336,6 +363,7 @@ PRODUCT_NAME = BaseViewControllerSwift; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -343,6 +371,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -353,6 +382,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.baseviewcontrollerswift.BaseViewControllerSwift; PRODUCT_NAME = BaseViewControllerSwift; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -365,6 +395,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.baseviewcontrollerswift.BaseViewControllerSwiftTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -376,6 +407,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.baseviewcontrollerswift.BaseViewControllerSwiftTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/BaseViewControllerSwift.xcodeproj/xcshareddata/xcschemes/BaseViewControllerSwift iOS.xcscheme b/BaseViewControllerSwift.xcodeproj/xcshareddata/xcschemes/BaseViewControllerSwift iOS.xcscheme index dcb17fc..27b997a 100644 --- a/BaseViewControllerSwift.xcodeproj/xcshareddata/xcschemes/BaseViewControllerSwift iOS.xcscheme +++ b/BaseViewControllerSwift.xcodeproj/xcshareddata/xcschemes/BaseViewControllerSwift iOS.xcscheme @@ -1,6 +1,6 @@ Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { var profile = Profile() profile.name = "Jane" let viewController = ProfileViewController(profile: profile) let navigationController = UINavigationController(rootViewController: viewController) - navigationController.navigationBar.translucent = false + navigationController.navigationBar.isTranslucent = false - window = UIWindow(frame: UIScreen.mainScreen().bounds) + window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = navigationController window?.makeKeyAndVisible() @@ -37,4 +37,3 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } - diff --git a/Example/ProfileView.swift b/Example/ProfileView.swift index d0acf37..a195d74 100644 --- a/Example/ProfileView.swift +++ b/Example/ProfileView.swift @@ -16,40 +16,40 @@ final class ProfileView: UIView { let titleLabel = UILabel() let profileImage = UIImageView() - let finishedButton = UIButton(type: .System) + let finishedButton = UIButton(type: .system) - private let stackView = UIStackView() + fileprivate let stackView = UIStackView() // MARK: - Initializers convenience init() { - self.init(frame: CGRectZero) + self.init(frame: CGRect.zero) } override init(frame: CGRect) { super.init(frame: frame) - backgroundColor = UIColor.whiteColor() + backgroundColor = UIColor.white - titleLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleTitle1) + titleLabel.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.title1) stackView.addArrangedSubview(titleLabel) - profileImage.contentMode = .ScaleAspectFit + profileImage.contentMode = .scaleAspectFit stackView.addArrangedSubview(profileImage) - finishedButton.setTitle(NSLocalizedString("Finished", comment: ""), forState: .Normal) + finishedButton.setTitle(NSLocalizedString("Finished", comment: ""), for: UIControlState()) stackView.addArrangedSubview(finishedButton) - stackView.axis = .Vertical - stackView.distribution = .Fill - stackView.alignment = .Center + stackView.axis = .vertical + stackView.distribution = .fill + stackView.alignment = .center addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false - addConstraint(NSLayoutConstraint(item: stackView, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1.0, constant: 0.0)) - addConstraint(NSLayoutConstraint(item: stackView, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1.0, constant: 0.0)) - addConstraint(NSLayoutConstraint(item: stackView, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1.0, constant: 0.0)) - addConstraint(NSLayoutConstraint(item: stackView, attribute: .Right, relatedBy: .Equal, toItem: self, attribute: .Right, multiplier: 1.0, constant: 0.0)) + addConstraint(NSLayoutConstraint(item: stackView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0.0)) + addConstraint(NSLayoutConstraint(item: stackView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0.0)) + addConstraint(NSLayoutConstraint(item: stackView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0.0)) + addConstraint(NSLayoutConstraint(item: stackView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0.0)) } required init?(coder aDecoder: NSCoder) { diff --git a/Example/ProfileViewController.swift b/Example/ProfileViewController.swift index 4aa858f..c21f8ce 100644 --- a/Example/ProfileViewController.swift +++ b/Example/ProfileViewController.swift @@ -16,7 +16,7 @@ final class ProfileViewController: BaseViewController { // MARK: - Properties - private let profile: Profile + fileprivate let profile: Profile // MARK: - Initializers @@ -27,6 +27,10 @@ final class ProfileViewController: BaseViewController { super.init() } + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + // MARK: - View Lifecycle @@ -34,7 +38,7 @@ final class ProfileViewController: BaseViewController { super.setupView() underlyingView.titleLabel.text = profile.name - underlyingView.finishedButton.addTarget(self, action: Selector("finishedButtonPressed:"), forControlEvents: .TouchUpInside) + underlyingView.finishedButton.addTarget(self, action: #selector(ProfileViewController.finishedButtonPressed(_:)), for: .touchUpInside) } override func setupAccessibility() { @@ -46,14 +50,13 @@ final class ProfileViewController: BaseViewController { // MARK: - Control Actions - func finishedButtonPressed(sender: UIButton) { - let alertController = UIAlertController(title: nil, message: "🎉", preferredStyle: .Alert) + func finishedButtonPressed(_ sender: UIButton) { + let alertController = UIAlertController(title: nil, message: "🎉", preferredStyle: .alert) - let doneAction = UIAlertAction(title: NSLocalizedString("Done", comment: ""), style: .Default, handler: nil) + let doneAction = UIAlertAction(title: NSLocalizedString("Done", comment: ""), style: .default, handler: nil) alertController.addAction(doneAction) - presentViewController(alertController, animated: true, completion: nil) + present(alertController, animated: true, completion: nil) } } - diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..f37673f --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem 'fastlane' +gem 'cocoapods', '~> 1.1.0.rc.3' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..f5d7ce3 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,281 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.7.1) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.4.0) + babosa (1.0.2) + cert (1.4.3) + fastlane_core (>= 0.52.1, < 1.0.0) + spaceship (>= 0.34.2, < 1.0.0) + claide (1.0.1) + cocoapods (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.1, < 2.0) + cocoapods-core (= 1.1.0.rc.3) + cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-downloader (>= 1.1.1, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-stats (>= 1.0.0, < 2.0) + cocoapods-trunk (= 1.1.0.beta.1) + cocoapods-try (>= 1.1.0, < 2.0) + colored (~> 1.2) + escape (~> 0.0.4) + fourflusher (~> 2.0) + gh_inspector (~> 1.0) + molinillo (~> 0.5.1) + nap (~> 1.0) + xcodeproj (>= 1.3.2, < 2.0) + cocoapods-core (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + cocoapods-deintegrate (1.0.1) + cocoapods-downloader (1.1.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.0) + cocoapods-stats (1.0.0) + cocoapods-trunk (1.1.0.beta.1) + nap (>= 0.8, < 2.0) + netrc (= 0.7.8) + cocoapods-try (1.1.0) + colored (1.2) + commander (4.4.0) + highline (~> 1.7.2) + credentials_manager (0.16.2) + colored + commander (>= 4.3.5) + highline (>= 1.7.1) + security + deliver (1.14.2) + credentials_manager (>= 0.16.1, < 1.0.0) + fastimage (~> 1.6) + fastlane_core (>= 0.52.1, < 1.0.0) + plist (>= 3.1.0, < 4.0.0) + spaceship (>= 0.35.0, < 1.0.0) + domain_name (0.5.20160826) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.1.1) + escape (0.0.4) + excon (0.53.0) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.6) + faraday (>= 0.7.4) + http-cookie (~> 1.0.0) + faraday_middleware (0.10.0) + faraday (>= 0.7.4, < 0.10) + fastimage (1.6.8) + addressable (~> 2.3, >= 2.3.5) + fastlane (1.105.2) + activesupport (< 5) + addressable (>= 2.3, < 3.0.0) + bundler (~> 1.12) + cert (>= 1.4.3, < 2.0.0) + credentials_manager (>= 0.16.1, < 1.0.0) + deliver (>= 1.14.2, < 2.0.0) + fastlane_core (>= 0.52.1, < 1.0.0) + frameit (>= 2.8.0, < 3.0.0) + gym (>= 1.11.0, < 2.0.0) + krausefx-shenzhen (>= 0.14.10, < 1.0.0) + match (>= 0.8.1, < 1.0.0) + multipart-post (~> 2.0.0) + pem (>= 1.3.2, < 2.0.0) + pilot (>= 1.10.1, < 2.0.0) + plist (>= 3.1.0, < 4.0.0) + produce (>= 1.2.1, < 2.0.0) + scan (>= 0.13.1, < 1.0.0) + screengrab (>= 0.5.2, < 1.0.0) + sigh (>= 1.11.2, < 2.0.0) + slack-notifier (>= 1.3, < 2.0.0) + snapshot (>= 1.16.2, < 2.0.0) + spaceship (>= 0.35.0, < 1.0.0) + supply (>= 0.7.1, < 1.0.0) + terminal-notifier (>= 1.6.2, < 2.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + word_wrap (~> 1.0.0) + xcode-install (~> 2.0.0) + xcodeproj (>= 0.20, < 2.0.0) + xcpretty (>= 0.2.3) + fastlane_core (0.52.1) + babosa + colored + commander (>= 4.4.0, <= 5.0.0) + credentials_manager (>= 0.16.1, < 1.0.0) + excon (>= 0.45.0, < 1.0) + gh_inspector (>= 1.0.1, < 2.0.0) + highline (>= 1.7.2) + json + multi_json + plist (~> 3.1) + rubyzip (~> 1.1.6) + terminal-table (~> 1.4.5) + fourflusher (2.0.1) + frameit (2.8.0) + deliver (> 0.3) + fastimage (~> 1.6.3) + fastlane_core (>= 0.52.1, < 1.0.0) + mini_magick (~> 4.5.1) + fuzzy_match (2.0.4) + gh_inspector (1.0.2) + google-api-client (0.9.15) + addressable (~> 2.3) + googleauth (~> 0.5) + httpclient (~> 2.7) + hurley (~> 0.1) + memoist (~> 0.11) + mime-types (>= 1.6) + representable (~> 2.3.0) + retriable (~> 2.0) + googleauth (0.5.1) + faraday (~> 0.9) + jwt (~> 1.4) + logging (~> 2.0) + memoist (~> 0.12) + multi_json (~> 1.11) + os (~> 0.9) + signet (~> 0.7) + gym (1.11.2) + fastlane_core (>= 0.52.1, < 1.0.0) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 1.1.7) + terminal-table (>= 1.4.5, < 2.0.0) + xcpretty (>= 0.2.4, < 1.0.0) + highline (1.7.8) + http-cookie (1.0.3) + domain_name (~> 0.5) + httpclient (2.8.2.4) + hurley (0.2) + i18n (0.7.0) + json (1.8.3) + jwt (1.5.6) + krausefx-shenzhen (0.14.10) + commander (>= 4.3, < 5.0) + dotenv (>= 0.7) + faraday (~> 0.9) + faraday_middleware (~> 0.9) + highline (>= 1.7.2) + json (~> 1.8) + net-sftp (~> 2.1.2) + plist (~> 3.1.0) + rubyzip (~> 1.1) + security (~> 0.1.3) + terminal-table (~> 1.4.5) + little-plugger (1.1.4) + logging (2.1.0) + little-plugger (~> 1.1) + multi_json (~> 1.10) + match (0.8.1) + cert (>= 1.4.3, < 2.0.0) + credentials_manager (>= 0.16.1, < 1.0.0) + fastlane_core (>= 0.52.1, < 1.0.0) + security + sigh (>= 1.11.2, < 2.0.0) + spaceship (>= 0.34.2, < 1.0.0) + memoist (0.15.0) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mini_magick (4.5.1) + minitest (5.9.1) + molinillo (0.5.1) + multi_json (1.12.1) + multi_xml (0.5.5) + multipart-post (2.0.0) + nap (1.1.0) + net-sftp (2.1.2) + net-ssh (>= 2.6.5) + net-ssh (3.2.0) + netrc (0.7.8) + os (0.9.6) + pem (1.3.2) + fastlane_core (>= 0.43.1, < 1.0.0) + spaceship (>= 0.26.2, < 1.0.0) + pilot (1.10.1) + credentials_manager (>= 0.16.0) + fastlane_core (>= 0.52.1, < 1.0.0) + spaceship (>= 0.34.2, < 1.0.0) + terminal-table (~> 1.4.5) + plist (3.1.0) + produce (1.2.1) + fastlane_core (>= 0.52.1, < 1.0.0) + spaceship (>= 0.34.2, < 1.0.0) + representable (2.3.0) + uber (~> 0.0.7) + retriable (2.1.0) + rouge (1.11.1) + rubyzip (1.1.7) + scan (0.13.1) + fastlane_core (>= 0.52.1, < 1.0.0) + slack-notifier (~> 1.3) + terminal-table + xcpretty (>= 0.2.2) + xcpretty-travis-formatter (>= 0.0.3) + screengrab (0.5.5) + fastlane_core (>= 0.52.1, < 1.0.0) + security (0.1.3) + sigh (1.11.2) + fastlane_core (>= 0.52.1, < 1.0.0) + plist (~> 3.1) + spaceship (>= 0.34.2, < 1.0.0) + signet (0.7.3) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (~> 1.5) + multi_json (~> 1.10) + slack-notifier (1.5.1) + snapshot (1.16.2) + fastimage (~> 1.6.3) + fastlane_core (>= 0.52.1, < 1.0.0) + plist (~> 3.1.0) + xcpretty (>= 0.2.3) + spaceship (0.36.0) + colored + credentials_manager (>= 0.16.0) + faraday (~> 0.9) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 0.9) + fastimage (~> 1.6) + multi_xml (~> 0.5) + plist (>= 3.1.0, < 4.0.0) + supply (0.7.1) + credentials_manager (>= 0.15.0) + fastlane_core (>= 0.43.4) + google-api-client (~> 0.9.1) + terminal-notifier (1.7.1) + terminal-table (1.4.5) + thread_safe (0.3.5) + tzinfo (1.2.2) + thread_safe (~> 0.1) + uber (0.0.15) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2) + word_wrap (1.0.0) + xcode-install (2.0.7) + claide (>= 0.9.1, < 1.1.0) + spaceship (>= 0.25.1, < 1.0.0) + xcodeproj (1.3.2) + activesupport (>= 3) + claide (>= 1.0.1, < 2.0) + colored (~> 1.2) + xcpretty (0.2.4) + rouge (~> 1.8) + xcpretty-travis-formatter (0.0.4) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods (~> 1.1.0.rc.3) + fastlane + +BUNDLED WITH + 1.13.3 diff --git a/README.md b/README.md index 594ec8f..3530aa7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # BaseViewController -The BaseViewController framework provides an organizational tool for writing custom view controllers using `UIKit`. This framework is written using Swift 2.1. It has been developed and used by iOS developers at [ustwo](ustwo.com). +The BaseViewController framework provides an organizational tool for writing custom view controllers using `UIKit`. This framework is written using Swift 3.0. It has been developed and used by iOS developers at [ustwo](https://ustwo.com/). ## Dependencies @@ -12,6 +12,15 @@ The BaseViewController framework provides an organizational tool for writing cus ## Installation +### BaseViewControllerSwift version vs Swift version. + +Because of the many Swift versions BaseViewControllerSwift supports, it might be confusing to find the version of BaseViewControllerSwift that you need. Below is a table that shows which version of BaseViewControllerSwift you should use for your Swift version. + +| Swift version | BaseViewControllerSwift version | +| ------------- | --------------- | +| 3.0 | 2.0.0 | +| 2.1 | 1.0.0 | + ### CocoaPods [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: @@ -27,7 +36,7 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.3' use_frameworks! -pod 'BaseViewControllerSwift', '~> 1.0' +pod 'BaseViewControllerSwift', '~> 2.0' ``` Then, run the following command: @@ -68,10 +77,10 @@ Use the `setupView()` function to add target/actions to controls, set dynamicall ```swift override func setupView() { - super.setupView() - - underlyingView.titleLabel.text = profile.name - underlyingView.finishedButton.addTarget(self, action: Selector("finishedButtonPressed:"), forControlEvents: .TouchUpInside) + super.setupView() + + underlyingView.titleLabel.text = profile.name + underlyingView.finishedButton.addTarget(self, action: #selector(ProfileViewController.finishedButtonPressed(_:)), for: .touchUpInside) } ``` @@ -81,18 +90,20 @@ Use the `setupAccessibility()` function to add dynamically generated accessibili ```swift override func setupAccessibility() { - super.setupAccessibility() - - underlyingView.profileImage.accessibilityLabel = NSLocalizedString("Image of", comment: "") + " " + profile.name + super.setupAccessibility() + + underlyingView.profileImage.accessibilityLabel = NSLocalizedString("Image of", comment: "") + " " + profile.name } ``` +## Maintainers + +* Shagun Madhikarmi (@madhikarma) +* Aaron McTavish (@aamctustwo) -## Contributors +## Contact -* [Shagun Madhikarmi](mailto:shagun@ustwo.com) -* [Aaron McTavish](mailto:aamct@ustwo.com) -* [Martin Stolz](mailto:martin@ustwo.com) +* [open.source@ustwo.com](mailto:open.source@ustwo.com) ## License diff --git a/Sources/BaseViewController.swift b/Sources/BaseViewController.swift index bed067a..b5a6668 100644 --- a/Sources/BaseViewController.swift +++ b/Sources/BaseViewController.swift @@ -10,12 +10,12 @@ import UIKit /// Generic base view controller that automatically loads the underlying `BaseView` of type `T`. -public class BaseViewController: UIViewController { +open class BaseViewController: UIViewController { // MARK: - Properties - public var underlyingView: T { + open var underlyingView: T { if let myView = view as? T { return myView } @@ -31,15 +31,19 @@ public class BaseViewController: UIViewController { public init() { super.init(nibName: nil, bundle: nil) } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } // MARK: - View Lifecycle - public override func loadView() { + open override func loadView() { view = T() } - public override func viewDidLoad() { + open override func viewDidLoad() { super.viewDidLoad() setupView() @@ -50,14 +54,13 @@ public class BaseViewController: UIViewController { // MARK: - Setup // Abstract method. Subclasses should override this method to setup their view. - public func setupView() { + open func setupView() { } // Abstract method. Subclasses should override this method to add accessibility. - public func setupAccessibility() { + open func setupAccessibility() { } } - diff --git a/Sources/Info.plist b/Sources/Info.plist index d3de8ee..7e7479f 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 2.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 0000000..9013a91 --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,45 @@ +desc "Runs tests on the primary platforms and configurations" +lane :test do + verify( + scheme: "BaseViewControllerSwift iOS", + destination: "OS=10.0,name=iPhone 7 Plus", + sdk: "iphonesimulator10.0" + ) + verify_demo + pod_lib_lint +end + +desc "Runs unit tests" +lane :verify do |options| + scheme = options[:scheme] + destination = options[:destination] + sdk = options[:sdk] + output_directory = "fastlane/test_output/" + scheme + "/" + opts = { + :workspace => 'BaseViewControllerSwift.xcworkspace', + :scheme => scheme, + :destination => destination, + :sdk => sdk, + :code_coverage => true, + :xcargs => "ONLY_ACTIVE_ARCH=YES", + :output_directory => output_directory, + :clean => true + } + scan(opts) +end + +desc "Build demo app" +lane :verify_demo do + scheme = "iOS Example" + output_directory = "fastlane/test_output/" + scheme + "/" + xcodebuild( + workspace: "BaseViewControllerSwift.xcworkspace", + scheme: scheme, + destination: "OS=10.0,name=iPhone 7 Plus", + sdk: "iphonesimulator10.0", + xcargs: "ONLY_ACTIVE_ARCH=NO", + output_directory: output_directory, + clean: true, + build: true + ) +end diff --git a/fastlane/README.md b/fastlane/README.md new file mode 100644 index 0000000..3d64e29 --- /dev/null +++ b/fastlane/README.md @@ -0,0 +1,28 @@ +fastlane documentation +================ +# Installation +``` +sudo gem install fastlane +``` +# Available Actions +### test +``` +fastlane test +``` +Runs tests on the primary platforms and configurations +### verify +``` +fastlane verify +``` +Runs unit tests +### verify_demo +``` +fastlane verify_demo +``` +Build demo app + +---- + +This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. +More information about fastlane can be found on [https://fastlane.tools](https://fastlane.tools). +The documentation of fastlane can be found on [GitHub](https://github.com/fastlane/fastlane/tree/master/fastlane). diff --git a/fastlane/travis.sh b/fastlane/travis.sh new file mode 100755 index 0000000..f9387d2 --- /dev/null +++ b/fastlane/travis.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +fastlane test diff --git a/iOS Example.xcodeproj/project.pbxproj b/iOS Example.xcodeproj/project.pbxproj index b1e323e..9de1890 100644 --- a/iOS Example.xcodeproj/project.pbxproj +++ b/iOS Example.xcodeproj/project.pbxproj @@ -98,6 +98,7 @@ 00E0F5C71C3D16E8001478FB /* Sources */, 00E0F5C81C3D16E8001478FB /* Frameworks */, 00E0F5C91C3D16E8001478FB /* Resources */, + 006F491E1DB5054300C8F4FC /* ShellScript */, ); buildRules = ( ); @@ -115,11 +116,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = BaseViewControllerSwift; TargetAttributes = { 00E0F5CA1C3D16E8001478FB = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; }; }; @@ -153,6 +155,22 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 006F491E1DB5054300C8F4FC /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"SwiftLint does not exist, download from https://github.com/realm/SwiftLint\"\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 00E0F5C71C3D16E8001478FB /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -181,8 +199,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -209,6 +229,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -226,8 +247,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -246,6 +269,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -262,6 +287,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.baseviewcontrollerswift.iOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -275,6 +301,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.baseviewcontrollerswift.iOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/iOS Example.xcodeproj/xcshareddata/xcschemes/iOS Example.xcscheme b/iOS Example.xcodeproj/xcshareddata/xcschemes/iOS Example.xcscheme index df2d143..80cafa2 100644 --- a/iOS Example.xcodeproj/xcshareddata/xcschemes/iOS Example.xcscheme +++ b/iOS Example.xcodeproj/xcshareddata/xcschemes/iOS Example.xcscheme @@ -1,6 +1,6 @@