52 Commits

Author SHA1 Message Date
Matt Coneybeare
b92da20460 Remove the deprecated ct parameter 2020-12-04 08:49:35 -05:00
Matt Coneybeare
c54a35059c version bump 2019-10-30 18:47:53 -04:00
Matt Coneybeare
fedb19b8a7 Merge pull request #135 from weakfl/swift5
Update to Swift 5
2019-10-25 11:21:18 -04:00
weak
51eca2a931 Conversion to Swift 5
- convert all targets to Swift 5
- bump .swift-version
- update podspec
- fix warnings
2019-09-19 10:47:04 +02:00
weak
b22a605285 update projects to recommended settings 2019-09-19 10:23:37 +02:00
Matt Coneybeare
118a777ff2 Merge pull request #125 from samwize/master
Enable useStoreKitReviewPrompt for macOS 10.4+
2018-12-15 08:39:28 -05:00
Junda
690bf6be67 Enable useStoreKitReviewPrompt for macOS 10.4+ 2018-11-28 15:24:53 +08:00
Matt Coneybeare
1ea2201dd3 bump podspec 2018-10-29 15:04:25 -04:00
Matt Coneybeare
fb6e2444be Merge pull request #123 from metasmile/patch-1
add "s.swift_version = '4.2'"
2018-10-04 08:30:36 -04:00
metasmile
ddc5a0d7ea Update Armchair.podspec 2018-10-02 18:21:15 +02:00
Matt Coneybeare
7f05ad9ef6 Merge pull request #122 from bitsfabrik/master
change cancel action style & swift 4.2 changes
2018-09-28 07:55:56 -04:00
BiNo
94817f1715 swift 4.2 fix 2018-09-18 14:05:52 +02:00
BiNo
abeb3eb4b1 Merge branch 'master_original' 2018-09-18 13:56:02 +02:00
Matt Coneybeare
3d9c47bf60 Merge pull request #121 from metasmile/master
Remove Xcode warning forArmchair.swift:720:14
2018-08-31 14:32:13 -04:00
metasmile
fcd99c015a Merge pull request #1 from metasmile/metasmile-patch-1
Remove Xcode warning forArmchair.swift:720:14
2018-08-29 17:41:33 +02:00
metasmile
66fb9abb8d Remove Xcode warning forArmchair.swift:720:14
'let' properties are implicitly 'final'; use 'public' instead of 'open'
2018-08-29 17:40:29 +02:00
Philip Messlehner
d5ba63a0a4 removed duplicate cancel action 2018-07-24 10:38:09 +02:00
Philip Messlehner
44b930169c changed ordering and make use of cancel action 2018-07-24 10:28:57 +02:00
Matt Coneybeare
f7ed2b2063 Merge pull request #119 from mabidakun/Xcode-9.3-Swift-4.1-Fixes
Xcode 9.3 swift 4.1 fixes
2018-04-09 06:40:38 -04:00
Mike O. Abidakun
de6e53da44 Applies Xcode-9.3. Fix-it which adds compile time warnings for the implicit retention of self. 2018-03-30 21:38:58 +01:00
Mike O. Abidakun
ead9ec4656 Replaces code for checking the platform and OS version, with a simplified call that meets the original intent.
The original intent was to check if the code was running in an iOS simulator on an x86 architecture.
This solution was provided by a FixIt in Xcode-9.3.
2018-03-30 21:36:44 +01:00
Mike O. Abidakun
ffd05b16a5 Fixes a compile-time failure caused by referening to the useStoreKitReviewPrompt method, which is no included for macOS. 2018-03-30 21:33:37 +01:00
Matt Coneybeare
a8c1dfdae5 Merge pull request #112 from MartinMoizard/master
Improve iOS 10.3 review dialog support + documentation
2017-11-10 12:16:23 -05:00
Martin Moizard
b3bd6ecc16 Restore func hideRatingAlert() 2017-11-10 17:11:29 +01:00
Matt Coneybeare
773c9c9ddd Merge pull request #111 from 1bannamgiauten/patch-1
missing ; in end of line one
2017-10-29 12:43:59 -04:00
Martin Moizard
90ce675259 Add documentation on new API 2017-10-27 10:53:51 +02:00
Tuan Nguyen
f53bf4637d missing ; in end of line one 2017-10-21 01:12:17 +07:00
Matt Coneybeare
804141486d update podspec 2017-10-11 14:28:33 -04:00
Matt Coneybeare
86bb26031d updated iOS 11 review string template 2017-10-11 12:54:42 -04:00
Matt Coneybeare
74ae451630 updated iOS 11 review string template 2017-10-11 11:46:01 -04:00
Matt Coneybeare
c70e28dd42 Merge branch 'master' of github.com:UrbanApps/Armchair 2017-10-11 11:41:39 -04:00
Matt Coneybeare
04208a6f75 Merge pull request #110 from ArturoLee/master
Rate Button is now Bold
2017-10-05 11:27:07 -04:00
ArturoLee
5c963bda6a UIAlertActionStyle.cancel was assigned to the rate button so it can appear bold.
UIAlertActionStyle.default was assigned to the cancel button so it can have a regular font 2017-10-02 19:41:34 -04:00
Matt Coneybeare
04cb290dc1 updated podspec 2017-09-17 08:23:23 -04:00
Matt Coneybeare
a4f97f92c3 updated podspec 2017-09-15 09:20:14 -04:00
Matt Coneybeare
dfb230dcd2 Swift 4 and tweaks to example projects 2017-09-14 20:40:16 -04:00
Matt Coneybeare
87d68ec2a7 Updating podspec 2017-09-14 19:14:02 -04:00
Matt Coneybeare
3c95c3df2d Merge pull request #107 from MartinMoizard/swift3-and-root-fix
Fix issue when `getRootViewController` would return `nil`
2017-09-08 21:32:38 -04:00
Martin Moizard
eaebe860da Fix issue when getRootViewController would return nil 2017-09-01 09:56:47 +02:00
Martin Moizard
2bdd30f9ed Migrate to Swift 3 2017-09-01 09:56:15 +02:00
whitepixelstudios
adc0a0d580 Update iOS 10.3 review dialog support 2017-07-31 12:25:05 +10:00
whitepixelstudios
dddaa62c25 Changes 2017-07-31 11:52:04 +10:00
whitepixelstudios
ea3ab5ed28 Merge remote-tracking branch 'UrbanApps/master'
# Conflicts:
#	Source/Armchair.swift
2017-07-31 11:50:17 +10:00
whitepixelstudios
068c4b92c1 Remove ios < 9 support [Alertview] 2017-07-31 11:44:12 +10:00
Matt Coneybeare
ee3d999eb3 Merge pull request #94 from TenPercentHappier/master
Ensure didDisplayAlertClosure called for UIAlertController
2017-05-12 10:46:36 -04:00
Matt Coneybeare
cc623a0157 Merge pull request #95 from ari3l/master
Fix infinite prompts when using StoreKit prompt
2017-05-12 10:43:25 -04:00
Ariel
0db2bb6fb0 Fix infinite prompts when using StoreKit prompt 2017-05-11 13:00:32 -04:00
rainesbt
6163929275 Ensure didDisplayAlertClosure called for UIAlertController
* didDisplayAlertClosure not being called in the case of using UIAlertView
2017-05-10 14:58:42 -04:00
Matt Coneybeare
1949d8f07e Merge pull request #92 from ari3l/master
Add support for iOS 10.3 review prompt
2017-05-07 19:08:42 -04:00
Ariel
7299a7067a Add support for iOS 10.3 review prompt
Added an option to use SKStoreReviewController review prompt instead of the default prompt. If it’s not available (below iOS 10.3), just use the default prompt.
2017-05-05 15:38:20 -04:00
Matt Coneybeare
f9736d6273 Merge pull request #89 from masgharneya/bugfix/useSwift3ToolchainOnRelease
Fixed issue with Carthage building project using the wrong toolchain
2017-03-17 11:15:54 -04:00
Mohammad Asgharneya
14c89be4b9 Fixed issue with Carthage building project using the wrong toolchain 2017-03-16 14:59:04 -04:00
16 changed files with 355 additions and 206 deletions

View File

@@ -1 +1 @@
3.0
5.0

View File

@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "Armchair"
s.version = "0.3.0"
s.version = "0.3.7"
s.summary = "A simple yet powerful App Review Manager for iOS and OSX in Swift"
s.description = <<-DESC
A simple yet powerful App Review Manager for iOS and OSX in Swift.
@@ -22,11 +22,12 @@ Pod::Spec.new do |s|
s.source = { :git => 'https://github.com/UrbanApps/Armchair.git', :tag => s.version }
s.license = { :type => "MIT", :file => "LICENSE" }
s.source_files = "Source/*.{h,swift}"
s.resources = "Localization/*.lproj"
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.10'
s.requires_arc = true
s.swift_version = '5.0'
end

View File

@@ -318,25 +318,29 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = Armchair;
TargetAttributes = {
E6A0AF6419C9CFF400C3A7DC = {
CreatedOnToolsVersion = 6.0;
ProvisioningStyle = Manual;
};
E6D8B8EF19C756A4001AD043 = {
LastSwiftMigration = 1100;
};
F8111E3219A95C8B0040E7D1 = {
CreatedOnToolsVersion = 6.0;
LastSwiftMigration = 0800;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = F8111E2D19A95C8B0040E7D1 /* Build configuration list for PBXProject "Armchair" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F8111E2919A95C8B0040E7D1;
productRefGroup = F8111E2919A95C8B0040E7D1;
@@ -541,7 +545,8 @@
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -566,7 +571,8 @@
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -613,18 +619,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -655,6 +670,7 @@
OTHER_SWIFT_FLAGS = "-DDebug";
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -665,18 +681,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -698,6 +723,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@@ -724,8 +750,7 @@
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -747,7 +772,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 5.0;
};
name = Release;
};

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F8111E3219A95C8B0040E7D1"
BuildableName = "Armchair.framework"
BlueprintName = "Armchair"
ReferencedContainer = "container:Armchair.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
@@ -39,17 +48,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F8111E3219A95C8B0040E7D1"
BuildableName = "Armchair.framework"
BlueprintName = "Armchair"
ReferencedContainer = "container:Armchair.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -70,8 +68,6 @@
ReferencedContainer = "container:Armchair.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -51,8 +49,6 @@
ReferencedContainer = "container:Armchair.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -28,12 +28,13 @@
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
AppDelegate.setupArmchair()
return true
}
}
let Pages = "361309726" // Pages iOS
let appID = "361309726" // Pages iOS
#elseif os(OSX)
@@ -43,9 +44,12 @@
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
override init() {
AppDelegate.setupArmchair()
}
}
let Pages = "409201541" // Pages Mac
let appID = "409201541" // Pages Mac
#else
#endif
@@ -54,10 +58,6 @@ import Armchair
extension AppDelegate {
override class func initialize() {
AppDelegate.setupArmchair()
}
class func setupArmchair() {
// Normally, all the setup would be here.
// But, because we are presenting a few different setups in the example,
@@ -68,7 +68,7 @@ extension AppDelegate {
// because it needs to receive application life-cycle notifications
//
// NOTE: The appID call always has to go before any other Armchair calls
Armchair.appID(Pages)
Armchair.appID(appID)
Armchair.debugEnabled(true)
}
}

View File

@@ -1,5 +1,15 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
@@ -30,6 +40,16 @@
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
@@ -59,6 +79,16 @@
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {

View File

@@ -55,12 +55,12 @@ extension ViewController {
// Only set it if we are using Armchair localizations
if !Armchair.useMainAppBundleForLocalizations() {
let currentLocalization: NSString = NSBundle.mainBundle().preferredLocalizations[0] as NSString
let currentLocalization: NSString = Bundle.main.preferredLocalizations[0] as NSString
// Only set it if we are using a different language than this apps development language
if let developmentLocalization = NSBundle.mainBundle().developmentLocalization {
if currentLocalization != developmentLocalization {
if let developmentLocalization = Bundle.main.developmentLocalization {
if currentLocalization as String != developmentLocalization {
languageLabelText = currentLocalization as String
if let displayName = NSLocale(localeIdentifier: currentLocalization as String).displayNameForKey(NSLocaleIdentifier, value:currentLocalization) {
if let displayName = (Locale(identifier: currentLocalization as String) as NSLocale).displayName(forKey: NSLocale.Key.identifier, value:currentLocalization) {
languageLabelText = "\(displayName): \(currentLocalization)"
}
}
@@ -78,7 +78,7 @@ extension ViewController {
resetAppReviewManager()
// The AppID is the only required setup
Armchair.appID(Pages)
Armchair.appID(appID)
// Debug means that it will popup on the next available change
Armchair.debugEnabled(true)
@@ -96,7 +96,7 @@ extension ViewController {
resetAppReviewManager()
// The AppID is the only required setup
Armchair.appID(Pages)
Armchair.appID(appID)
// Debug means that it will popup on the next available change
Armchair.debugEnabled(true)
@@ -143,7 +143,7 @@ extension ViewController {
Armchair.opensInStoreKit(false)
// This sets a custom tint color (applies only to UIAlertController).
Armchair.tintColor(UIColor.brownColor())
Armchair.tintColor(tintColor: UIColor.brown)
#endif
// This sets the Affiliate code you want to use, but is not required.
@@ -193,7 +193,7 @@ extension ViewController {
resetAppReviewManager()
// The AppID is the only required setup
Armchair.appID(Pages)
Armchair.appID(appID)
// Debug means that it will popup on the next available change
Armchair.debugEnabled(true)
@@ -216,11 +216,11 @@ extension ViewController {
}
@IBAction func openUrbanApps(_: AnyObject) {
if let url = NSURL(string: "http://urbanapps.com") {
if let url = URL(string: "http://urbanapps.com") {
#if os(iOS)
UIApplication.sharedApplication().openURL(url)
UIApplication.shared.openURL(url)
#elseif os(OSX)
NSWorkspace.sharedWorkspace().openURL(url)
NSWorkspace.shared.open(url)
#else
#endif
}

View File

@@ -1,4 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Cảm ơn bạn đã sử dụng ứng dụng %@ trong thời gian qua, bạn có thể dành chút thời gian để đánh giá ứng dụng trong AppStore không? Sẽ không mất quá 1 phút nhưng chúng tôi rất trân trọng điều đó!"
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Cảm ơn bạn đã sử dụng ứng dụng %@ trong thời gian qua, bạn có thể dành chút thời gian để đánh giá ứng dụng trong AppStore không? Sẽ không mất quá 1 phút nhưng chúng tôi rất trân trọng điều đó!";
"Rate %@" = "Đánh giá %@";
"No, Thanks" = "Không, xin cảm ơn";
"Remind me later" = "Hãy nhắc nhở tôi sau";

View File

@@ -33,13 +33,6 @@
remoteGlobalIDString = E6D8B8F919C756A4001AD043;
remoteInfo = ArmchairMac;
};
E60FA80119C90D3500179D70 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = E60FA7F719C90D3500179D70 /* Armchair.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = E6D8B92819C880A9001AD043;
remoteInfo = ArmchairTests;
};
E60FA80319C90D7100179D70 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = E60FA7F719C90D3500179D70 /* Armchair.xcodeproj */;
@@ -135,7 +128,6 @@
E60FA80019C90D3500179D70 /* Armchair.framework */,
E6F6156919C9FE8900C0B51C /* Armchair.bundle */,
E6F6159819CA003600C0B51C /* Armchair.bundle */,
E60FA80219C90D3500179D70 /* ArmchairTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -169,17 +161,18 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = Armchair;
TargetAttributes = {
E60FA7B919C908FE00179D70 = {
CreatedOnToolsVersion = 6.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = E60FA7B519C908FE00179D70 /* Build configuration list for PBXProject "Mac Example" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -216,13 +209,6 @@
remoteRef = E60FA7FF19C90D3500179D70 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
E60FA80219C90D3500179D70 /* ArmchairTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = ArmchairTests.xctest;
remoteRef = E60FA80119C90D3500179D70 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
E6F6156919C9FE8900C0B51C /* Armchair.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
@@ -296,17 +282,28 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
@@ -315,6 +312,7 @@
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -332,6 +330,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@@ -339,17 +338,28 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
@@ -358,6 +368,7 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -367,6 +378,8 @@
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
};
name = Release;
};
@@ -374,11 +387,13 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Example/Info-Mac.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.armchair.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -386,11 +401,13 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Example/Info-Mac.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.armchair.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
};
name = Release;
};

View File

@@ -284,6 +284,14 @@ Armchair.shouldPromptIfRated() -> Bool
Armchair.shouldPromptIfRated(shouldPromptIfRated: Bool)
```
The `useStoreKitReviewPrompt` configuration determines wether or not to try showing the SKStoreReviewController's requestReview() prompt instead of the default prompt. This setting has some effects only on iOS version >= 10.3. It's default value is `false`.
```swift
// GETTER
Armchair.useStoreKitReviewPrompt() -> Bool
// SETTER
Armchair.useStoreKitReviewPrompt(useStoreKitReviewPrompt: Bool)
```
The `useMainAppBundleForLocalizations` configuration is a way to tell Armchair that you are providing your own translations for the review prompt popup strings. This may be because you are just customizing them, or that you have set your own text for the popup. If set to `true`, the main bundle will always be used to load localized strings. You have to include the translations either in a file called `ArmchairLocalizable.strings` or the standard `Localizable.strings`. If set to `false` Armchair will look in its own translation bundle for the translating strings. It's default value is `false`.
```swift

View File

@@ -243,6 +243,13 @@ public func shouldPromptIfRated(_ shouldPromptIfRated: Bool) {
Manager.defaultManager.shouldPromptIfRated = shouldPromptIfRated
}
/*
* Return whether Armchair will try and present the Storekit review prompt (useful for custom dialog modification)
*/
public var shouldTryStoreKitReviewPrompt : Bool {
return Manager.defaultManager.shouldTryStoreKitReviewPrompt
}
/*
* If set to true, the main bundle will always be used to load localized strings.
* Set this to true if you have provided your own custom localizations in
@@ -270,7 +277,7 @@ public func affiliateCode(_ affiliateCode: String) {
}
/*
* If you are an Apple Affiliate, enter your campaign code here.
* If you are an Apple Affiliate, enter your campaign code here. (DEPRECATED)
* Default => "Armchair-<appID>"
*/
public func affiliateCampaignCode() -> String {
@@ -280,6 +287,18 @@ public func affiliateCampaignCode(_ affiliateCampaignCode: String) {
Manager.defaultManager.affiliateCampaignCode = affiliateCampaignCode
}
/*
* If set to true, use SKStoreReviewController's requestReview() prompt instead of the default prompt.
* If not on iOS 10.3+ or macOS 10.4+, resort to the default prompt.
* Default => false.
*/
public func useStoreKitReviewPrompt() -> Bool {
return Manager.defaultManager.useStoreKitReviewPrompt
}
public func useStoreKitReviewPrompt(_ useStoreKitReviewPrompt: Bool) {
Manager.defaultManager.useStoreKitReviewPrompt = useStoreKitReviewPrompt
}
/*
* 'true' will show the Armchair alert everytime. Useful for testing
* how your message looks and making sure the link to your app's review page works.
@@ -696,7 +715,7 @@ public enum ArmchairKey: String, CustomStringConvertible {
}
open class ArmchairTrackingInfo: CustomStringConvertible {
open let info: Dictionary<ArmchairKey, AnyObject>
public let info: Dictionary<ArmchairKey, AnyObject>
init(info: Dictionary<ArmchairKey, AnyObject>) {
self.info = info
@@ -728,7 +747,7 @@ public struct AppiraterKey {
// MARK: PRIVATE Interface
#if os(iOS)
open class ArmchairManager : NSObject, UIAlertViewDelegate, SKStoreProductViewControllerDelegate { }
open class ArmchairManager : NSObject, SKStoreProductViewControllerDelegate { }
#elseif os(OSX)
open class ArmchairManager : NSObject, NSAlertDelegate { }
#else
@@ -748,11 +767,12 @@ open class Manager : ArmchairManager {
// MARK: Review Alert & Properties
#if os(iOS)
fileprivate var ratingAlert: UIAlertView? = nil
fileprivate let reviewURLTemplate = "itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&id=APP_ID&at=AFFILIATE_CODE&ct=AFFILIATE_CAMPAIGN_CODE&action=write-review"
fileprivate var ratingAlert: UIAlertController? = nil
fileprivate let reviewURLTemplate = "itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&id=APP_ID&at=AFFILIATE_CODE&ct=AFFILIATE_CAMPAIGN_CODE&action=write-review"
fileprivate let reviewURLTemplateiOS11 = "https://itunes.apple.com/us/app/idAPP_ID?ls=1&mt=8&at=AFFILIATE_CODE&action=write-review"
#elseif os(OSX)
private var ratingAlert: NSAlert? = nil
private let reviewURLTemplate = "macappstore://itunes.apple.com/us/app/idAPP_ID?ls=1&mt=12&at=AFFILIATE_CODE&ct=AFFILIATE_CAMPAIGN_CODE"
private let reviewURLTemplate = "macappstore://itunes.apple.com/us/app/idAPP_ID?ls=1&mt=12&at=AFFILIATE_CODE"
#else
#endif
@@ -864,6 +884,7 @@ open class Manager : ArmchairManager {
// It is my affiliate code. It is better that somebody's code is used rather than nobody's.
fileprivate var affiliateCode: String = "11l7j9"
fileprivate var affiliateCampaignCode: String = "Armchair"
fileprivate var useStoreKitReviewPrompt: Bool = false
#if os(iOS)
fileprivate var usesAnimation: Bool = true
@@ -1191,63 +1212,87 @@ open class Manager : ArmchairManager {
return (daysBeforeReminding > 0 && remindButtonTitle != nil)
}
public var shouldTryStoreKitReviewPrompt : Bool {
#if os(iOS)
if #available(iOS 10.3, *), useStoreKitReviewPrompt {
return true
}
#endif
return false
}
fileprivate func requestStoreKitReviewPrompt() -> Bool {
if #available(iOS 10.3, OSX 10.14, *), useStoreKitReviewPrompt {
SKStoreReviewController.requestReview()
// Assume this version is rated. There is no API to tell if the user actaully rated.
userDefaultsObject?.setBool(true, forKey: keyForArmchairKeyType(ArmchairKey.RatedCurrentVersion))
userDefaultsObject?.setBool(true, forKey: keyForArmchairKeyType(ArmchairKey.RatedAnyVersion))
userDefaultsObject?.synchronize()
#if os(iOS)
closeModalPanel()
#endif
return true
}
return false
}
fileprivate func showRatingAlert() {
if let customClosure = customAlertClosure {
customClosure({[weak self] in self?._rateApp()}, {[weak self] in self?.remindMeLater()}, {[weak self] in self?.dontRate()})
customClosure({[weak self] in
if let result = self?.requestStoreKitReviewPrompt(), result {
///Showed storekit prompt, all done
} else {
/// Didn't show storekit prompt, present app store manually
self?._rateApp()
}
}, {[weak self] in self?.remindMeLater()}, {[weak self] in self?.dontRate()})
if let closure = self.didDisplayAlertClosure {
closure()
}
} else {
if requestStoreKitReviewPrompt() {
///Showed storekit prompt, all done
return
}
#if os(iOS)
if (operatingSystemVersion >= 8 && usesAlertController) || operatingSystemVersion >= 9 {
/* iOS 8 uses new UIAlertController API*/
let alertView : UIAlertController = UIAlertController(title: reviewTitle, message: reviewMessage, preferredStyle: UIAlertControllerStyle.alert)
alertView.addAction(UIAlertAction(title: cancelButtonTitle, style:UIAlertActionStyle.cancel, handler: {
/// Didn't show storekit prompt, present app store manually
let alertView : UIAlertController = UIAlertController(title: reviewTitle, message: reviewMessage, preferredStyle: .alert)
alertView.addAction(UIAlertAction(title: rateButtonTitle, style: .default, handler: {
(alert: UIAlertAction!) in
self._rateApp()
}))
if (showsRemindButton()) {
alertView.addAction(UIAlertAction(title: remindButtonTitle!, style: .default, handler: {
(alert: UIAlertAction!) in
self.dontRate()
self.remindMeLater()
}))
if (showsRemindButton()) {
alertView.addAction(UIAlertAction(title: remindButtonTitle!, style:UIAlertActionStyle.default, handler: {
(alert: UIAlertAction!) in
self.remindMeLater()
}))
}
alertView.addAction(UIAlertAction(title: rateButtonTitle, style:UIAlertActionStyle.default, handler: {
(alert: UIAlertAction!) in
self._rateApp()
}))
// get the top most controller (= the StoreKit Controller) and dismiss it
if let presentingController = UIApplication.shared.keyWindow?.rootViewController {
if let topController = topMostViewController(presentingController) {
topController.present(alertView, animated: usesAnimation) {
print("presentViewController() completed")
}
}
// note that tint color has to be set after the controller is presented in order to take effect (last checked in iOS 9.3)
alertView.view.tintColor = tintColor
}
} else {
/* Otherwise we use UIAlertView still */
var alertView: UIAlertView
if (showsRemindButton()) {
alertView = UIAlertView(title: reviewTitle, message: reviewMessage, delegate: self, cancelButtonTitle: cancelButtonTitle, otherButtonTitles: remindButtonTitle!, rateButtonTitle)
} else {
alertView = UIAlertView(title: reviewTitle, message: reviewMessage, delegate: self, cancelButtonTitle: cancelButtonTitle, otherButtonTitles: rateButtonTitle)
}
// If we have a remind button, show it first. Otherwise show the rate button
// If we have a remind button, show the rate button next. Otherwise stop adding buttons.
alertView.cancelButtonIndex = -1
ratingAlert = alertView
alertView.show()
if let closure = didDisplayAlertClosure {
closure()
}
}
alertView.addAction(UIAlertAction(title: cancelButtonTitle, style: .cancel, handler: {
(alert: UIAlertAction!) in
self.dontRate()
}))
ratingAlert = alertView
// get the top most controller (= the StoreKit Controller) and dismiss it
if let presentingController = UIApplication.shared.keyWindow?.rootViewController {
if let topController = Manager.topMostViewController(presentingController) {
topController.present(alertView, animated: usesAnimation) { [weak self] in
if let closure = self?.didDisplayAlertClosure {
closure()
}
print("presentViewController() completed")
}
}
// note that tint color has to be set after the controller is presented in order to take effect (last checked in iOS 9.3)
alertView.view.tintColor = tintColor
}
#elseif os(OSX)
let alert: NSAlert = NSAlert()
@@ -1260,14 +1305,14 @@ open class Manager : ArmchairManager {
alert.addButton(withTitle: cancelButtonTitle)
ratingAlert = alert
if let window = NSApplication.shared().keyWindow {
if let window = NSApplication.shared.keyWindow {
alert.beginSheetModal(for: window) {
(response: NSModalResponse) in
self.handleNSAlert(returnCode: response)
(response: NSApplication.ModalResponse) in
self.handleNSAlertResponse(response)
}
} else {
let returnCode = alert.runModal()
handleNSAlert(returnCode:returnCode)
let response = alert.runModal()
handleNSAlertResponse(response)
}
if let closure = self.didDisplayAlertClosure {
@@ -1283,19 +1328,6 @@ open class Manager : ArmchairManager {
// MARK: PRIVATE Alert View / StoreKit Delegate Methods
#if os(iOS)
open func alertView(_ alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int) {
// cancelButtonIndex is set to -1 to show the cancel button up top, but a tap on it ends up here with index 0
if (alertView.cancelButtonIndex == buttonIndex || 0 == buttonIndex) {
// they don't want to rate it
dontRate()
} else if (showsRemindButton() && 1 == buttonIndex) {
// remind them later
remindMeLater()
} else {
// they want to rate it
_rateApp()
}
}
//Delegate call from the StoreKit view.
open func productViewControllerDidFinish(_ viewController: SKStoreProductViewController!) {
@@ -1304,45 +1336,45 @@ open class Manager : ArmchairManager {
//Close the in-app rating (StoreKit) view and restore the previous status bar style.
fileprivate func closeModalPanel() {
let usedAnimation = usesAnimation
if modalPanelOpen {
UIApplication.shared.setStatusBarStyle(currentStatusBarStyle, animated:usesAnimation)
let usedAnimation = usesAnimation
modalPanelOpen = false
// get the top most controller (= the StoreKit Controller) and dismiss it
if let presentingController = UIApplication.shared.keyWindow?.rootViewController {
if let topController = topMostViewController(presentingController) {
topController.dismiss(animated: usesAnimation) {
if let closure = self.didDismissModalViewClosure {
closure(usedAnimation)
}
}
if let topController = Manager.topMostViewController(presentingController) {
topController.dismiss(animated: usesAnimation) {}
currentStatusBarStyle = UIStatusBarStyle.default
}
}
}
if let closure = self.didDismissModalViewClosure {
closure(usedAnimation)
}
}
#elseif os(OSX)
private func handleNSAlert(returnCode: NSInteger) {
switch (returnCode) {
case NSAlertFirstButtonReturn:
// they want to rate it
_rateApp()
case NSAlertSecondButtonReturn:
// remind them later or cancel
if showsRemindButton() {
remindMeLater()
} else {
dontRate()
}
case NSAlertThirdButtonReturn:
// they don't want to rate it
dontRate()
private func handleNSAlertResponse(_ response: NSApplication.ModalResponse) {
switch (response) {
case .alertFirstButtonReturn:
// they want to rate it
_rateApp()
case .alertSecondButtonReturn:
// remind them later or cancel
if showsRemindButton() {
remindMeLater()
} else {
dontRate()
}
case .alertThirdButtonReturn:
// they don't want to rate it
dontRate()
default:
return
}
return
}
}
#else
@@ -1398,7 +1430,7 @@ open class Manager : ArmchairManager {
}
if let rootController = getRootViewController() {
if let rootController = Manager.getRootViewController() {
rootController.present(storeViewController, animated: usesAnimation) {
self.modalPanelOpen = true
@@ -1414,8 +1446,8 @@ open class Manager : ArmchairManager {
UIApplication.shared.openURL(url)
}
}
// Check for iOS simulator
#if (arch(i386) || arch(x86_64)) && os(iOS)
#if targetEnvironment(simulator)
debugLog("iTunes App Store is not supported on the iOS simulator.")
debugLog(" - We would have went to \(reviewURLString()).")
debugLog(" - Try running on a test-device")
@@ -1425,7 +1457,7 @@ open class Manager : ArmchairManager {
#elseif os(OSX)
if let url = URL(string: reviewURLString()) {
let opened = NSWorkspace.shared().open(url)
let opened = NSWorkspace.shared.open(url)
if !opened {
debugLog("Failed to open \(url)")
}
@@ -1436,10 +1468,14 @@ open class Manager : ArmchairManager {
}
fileprivate func reviewURLString() -> String {
let template = reviewURLTemplate
#if os(iOS)
let template = operatingSystemVersion >= 11 ? reviewURLTemplateiOS11 : reviewURLTemplate
#elseif os(OSX)
let template = reviewURLTemplate
#else
#endif
var reviewURL = template.replacingOccurrences(of: "APP_ID", with: "\(appID)")
reviewURL = reviewURL.replacingOccurrences(of: "AFFILIATE_CODE", with: "\(affiliateCode)")
reviewURL = reviewURL.replacingOccurrences(of: "AFFILIATE_CAMPAIGN_CODE", with: "\(affiliateCampaignCode)")
return reviewURL
}
@@ -1665,7 +1701,7 @@ open class Manager : ArmchairManager {
}
#if os(iOS)
private func topMostViewController(_ controller: UIViewController?) -> UIViewController? {
private static func topMostViewController(_ controller: UIViewController?) -> UIViewController? {
var isPresenting: Bool = false
var topController: UIViewController? = controller
repeat {
@@ -1683,14 +1719,14 @@ open class Manager : ArmchairManager {
return topController
}
private func getRootViewController() -> UIViewController? {
private static func getRootViewController() -> UIViewController? {
if var window = UIApplication.shared.keyWindow {
if window.windowLevel != UIWindowLevelNormal {
if window.windowLevel != UIWindow.Level.normal {
let windows: NSArray = UIApplication.shared.windows as NSArray
for candidateWindow in windows {
if let candidateWindow = candidateWindow as? UIWindow {
if candidateWindow.windowLevel == UIWindowLevelNormal {
if candidateWindow.windowLevel == UIWindow.Level.normal {
window = candidateWindow
break
}
@@ -1698,34 +1734,47 @@ open class Manager : ArmchairManager {
}
}
for subView in window.subviews {
if let responder = subView.next {
if responder.isKind(of: UIViewController.self) {
return topMostViewController(responder as? UIViewController)
}
}
}
return iterateSubViewsForViewController(window)
}
return nil
}
private static func iterateSubViewsForViewController(_ parentView: UIView) -> UIViewController? {
for subView in parentView.subviews {
if let responder = subView.next {
if responder.isKind(of: UIViewController.self) {
return topMostViewController(responder as? UIViewController)
}
}
if let found = iterateSubViewsForViewController(subView) {
return found
}
}
return nil
}
#endif
private func hideRatingAlert() {
if let alert = ratingAlert {
debugLog("Hiding Alert")
#if os(iOS)
if alert.isVisible {
alert.dismiss(withClickedButtonIndex: alert.cancelButtonIndex, animated: false)
let isAlertVisible = alert.isViewLoaded && alert.view.window != nil
if isAlertVisible {
alert.dismiss(animated: false, completion: {
self.dontRate()
})
}
#elseif os(OSX)
if let window = NSApplication.shared().keyWindow {
if let window = NSApplication.shared.keyWindow {
if let parent = window.sheetParent {
parent.endSheet(window)
}
}
#else
#endif
ratingAlert = nil
@@ -1743,12 +1792,12 @@ open class Manager : ArmchairManager {
// MARK: -
// MARK: Notification Handlers
public func appWillResignActive(_ notification: Notification) {
@objc public func appWillResignActive(_ notification: Notification) {
debugLog("appWillResignActive:")
hideRatingAlert()
}
public func applicationDidFinishLaunching(_ notification: Notification) {
@objc public func applicationDidFinishLaunching(_ notification: Notification) {
DispatchQueue.global(qos: .background).async {
self.debugLog("applicationDidFinishLaunching:")
self.migrateKeysIfNecessary()
@@ -1756,7 +1805,7 @@ open class Manager : ArmchairManager {
}
}
public func applicationWillEnterForeground(_ notification: Notification) {
@objc public func applicationWillEnterForeground(_ notification: Notification) {
DispatchQueue.global(qos: .background).async {
self.debugLog("applicationWillEnterForeground:")
self.migrateKeysIfNecessary()
@@ -1783,13 +1832,13 @@ open class Manager : ArmchairManager {
fileprivate func setupNotifications() {
#if os(iOS)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.appWillResignActive(_:)), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(UIApplicationDelegate.applicationDidFinishLaunching(_:)), name: NSNotification.Name.UIApplicationDidFinishLaunching, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(UIApplicationDelegate.applicationWillEnterForeground(_:)), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.appWillResignActive(_:)), name: UIApplication.willResignActiveNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.applicationDidFinishLaunching(_:)), name: UIApplication.didFinishLaunchingNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.applicationWillEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
#elseif os(OSX)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.appWillResignActive(_:)), name: NSNotification.Name.NSApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(NSApplicationDelegate.applicationDidFinishLaunching(_:)), name: NSNotification.Name.NSApplicationDidFinishLaunching, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.applicationWillEnterForeground(_:)), name: NSNotification.Name.NSApplicationWillBecomeActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.appWillResignActive(_:)), name: NSApplication.willResignActiveNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.applicationDidFinishLaunching(_:)), name: NSApplication.didFinishLaunchingNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Manager.applicationWillEnterForeground(_:)), name: NSApplication.willBecomeActiveNotification, object: nil)
#else
#endif

View File

@@ -87,9 +87,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
939461E32333725B00C8A00E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
939461E42333725B00C8A00E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
E60FA81719C9219600179D70 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
E66F854919D0A7C600AD80EC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
E6A0AF5D19C9C89E00C3A7DC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/Main.storyboard; sourceTree = "<group>"; };
E6C49DC519C23C91006A4544 /* iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
E6E5F4C219C8E18E008A6C1B /* armchair.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = armchair.jpg; sourceTree = "<group>"; };
E6E5F4CC19C8E388008A6C1B /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; };
@@ -188,22 +188,23 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = Armchair;
TargetAttributes = {
F8111E0419A951050040E7D1 = {
CreatedOnToolsVersion = 6.0;
DevelopmentTeam = 9H3S97RP4K;
LastSwiftMigration = 0800;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = F8111E0019A951050040E7D1 /* Build configuration list for PBXProject "iOS Example" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F8111DFC19A951050040E7D1;
productRefGroup = F8111DFC19A951050040E7D1;
@@ -303,7 +304,7 @@
E66F854819D0A7C600AD80EC /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
E66F854919D0A7C600AD80EC /* en */,
939461E42333725B00C8A00E /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
@@ -311,7 +312,7 @@
F8111E1019A951050040E7D1 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
E6A0AF5D19C9C89E00C3A7DC /* en */,
939461E32333725B00C8A00E /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
@@ -323,18 +324,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -362,6 +372,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -370,18 +381,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -401,6 +421,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@@ -411,7 +432,6 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
@@ -422,7 +442,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.armchair.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "iOS Example";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -431,7 +451,6 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
INFOPLIST_FILE = "$(SRCROOT)/Example/Info-iOS.plist";
@@ -440,7 +459,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.armchair.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "iOS Example";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 5.0;
};
name = Release;
};