Reset project to not use IB
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" "6.5.2"
|
|
@@ -1,8 +0,0 @@
|
|||||||
root_url:
|
|
||||||
https://promisekit.org/reference/
|
|
||||||
readme:
|
|
||||||
foo.md
|
|
||||||
exclude:
|
|
||||||
- Sources/Deprecations.swift
|
|
||||||
- Sources/AnyPromise.swift
|
|
||||||
|
|
@@ -1,8 +0,0 @@
|
|||||||
[PLEASE READ THE TROUBLESHOOTING GUIDE](https://github.com/mxcl/PromiseKit/blob/master/Documentation/Troubleshooting.md).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
You read the guide but it didn’t help? OK, we’re here to help.
|
|
||||||
|
|
||||||
* Please specify the PromiseKit major version you are using
|
|
||||||
* [Please format your code in triple backticks and ensure readable indentation](https://help.github.com/articles/creating-and-highlighting-code-blocks/)
|
|
@@ -1,19 +0,0 @@
|
|||||||
@testable import Core
|
|
||||||
@testable import A_
|
|
||||||
import XCTest
|
|
||||||
|
|
||||||
//TODO get this to run on CI and don’t have it committed
|
|
||||||
//NOTE problem is Sourcery doesn’t support Linux currently
|
|
||||||
//USAGE: cd PromiseKit/Sources/.. && sourcery --config .github/sourcery.yml
|
|
||||||
|
|
||||||
{% for type in types.classes|based:"XCTestCase" %}
|
|
||||||
extension {{ type.name }} {
|
|
||||||
static var allTests = [
|
|
||||||
{% for method in type.methods %}{% if method.parameters.count == 0 and method.shortName|hasPrefix:"test" %} ("{{ method.shortName }}", {{type.name}}.{{ method.shortName }}),
|
|
||||||
{% endif %}{% endfor %}]
|
|
||||||
}
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
XCTMain([
|
|
||||||
{% for type in types.classes|based:"XCTestCase" %}{% if not type.annotations.excludeFromLinuxMain %} testCase({{ type.name }}.allTests),
|
|
||||||
{% endif %}{% endfor %}])
|
|
@@ -1,281 +0,0 @@
|
|||||||
Pod::Spec.new do |s|
|
|
||||||
s.name = "PromiseKit"
|
|
||||||
|
|
||||||
`xcodebuild -project PromiseKit.xcodeproj -showBuildSettings` =~ /CURRENT_PROJECT_VERSION = ((\d\.)+\d)/
|
|
||||||
abort("No version detected") if $1.nil?
|
|
||||||
s.version = $1
|
|
||||||
|
|
||||||
s.source = {
|
|
||||||
:git => "https://github.com/mxcl/#{s.name}.git",
|
|
||||||
:tag => s.version,
|
|
||||||
:submodules => true
|
|
||||||
}
|
|
||||||
|
|
||||||
s.license = 'MIT'
|
|
||||||
s.summary = 'Promises for Swift & ObjC.'
|
|
||||||
s.homepage = 'http://promisekit.org'
|
|
||||||
s.description = 'A thoughtful and complete implementation of promises for iOS, macOS, watchOS and tvOS with first-class support for both Objective-C and Swift.'
|
|
||||||
s.social_media_url = 'https://twitter.com/mxcl'
|
|
||||||
s.authors = { 'Max Howell' => 'mxcl@me.com' }
|
|
||||||
s.documentation_url = 'http://promisekit.org/docs/'
|
|
||||||
s.default_subspecs = 'CorePromise', 'UIKit', 'Foundation'
|
|
||||||
s.requires_arc = true
|
|
||||||
|
|
||||||
# CocoaPods documentation (like usual) is unclear about the
|
|
||||||
# consequences of setting this; we support 3.2 THROUGH 4.2
|
|
||||||
# s.swift_version = '4.0'
|
|
||||||
|
|
||||||
# CocoaPods requires us to specify the root deployment targets
|
|
||||||
# even though for us it is nonsense. Our root spec has no
|
|
||||||
# sources.
|
|
||||||
s.ios.deployment_target = '8.0'
|
|
||||||
s.osx.deployment_target = '10.10'
|
|
||||||
s.watchos.deployment_target = '2.0'
|
|
||||||
s.tvos.deployment_target = '9.0'
|
|
||||||
|
|
||||||
s.pod_target_xcconfig = {
|
|
||||||
'OTHER_SWIFT_FLAGS' => '-DPMKCocoaPods',
|
|
||||||
}
|
|
||||||
|
|
||||||
s.subspec 'Accounts' do |ss|
|
|
||||||
ss.ios.source_files = ss.osx.source_files = 'Extensions/Accounts/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.osx.frameworks = 'Accounts'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'Alamofire' do |ss|
|
|
||||||
ss.source_files = 'Extensions/Alamofire/Sources/*'
|
|
||||||
ss.dependency 'Alamofire', '~> 4.0'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.11'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'AddressBook' do |ss|
|
|
||||||
ss.ios.source_files = 'Extensions/AddressBook/Sources/*'
|
|
||||||
ss.ios.frameworks = 'AddressBook'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'AssetsLibrary' do |ss|
|
|
||||||
ss.ios.source_files = 'Extensions/AssetsLibrary/Sources/*'
|
|
||||||
ss.ios.frameworks = 'AssetsLibrary'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'AVFoundation' do |ss|
|
|
||||||
ss.ios.source_files = 'Extensions/AVFoundation/Sources/*'
|
|
||||||
ss.ios.frameworks = 'AVFoundation'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'Bolts' do |ss|
|
|
||||||
ss.source_files = 'Extensions/Bolts/Sources/*'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.dependency 'Bolts', '~> 1.9.0'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'CloudKit' do |ss|
|
|
||||||
ss.source_files = 'Extensions/CloudKit/Sources/*'
|
|
||||||
ss.frameworks = 'CloudKit'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '10.0'
|
|
||||||
ss.osx.deployment_target = '10.12'
|
|
||||||
ss.tvos.deployment_target = '10.0'
|
|
||||||
ss.watchos.deployment_target = '3.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'CoreBluetooth' do |ss|
|
|
||||||
ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/CoreBluetooth/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'CoreBluetooth'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'CorePromise' do |ss|
|
|
||||||
hh = Dir['Sources/*.h'] - Dir['Sources/*+Private.h']
|
|
||||||
|
|
||||||
cc = Dir['Sources/*.swift'] - ['Sources/SwiftPM.swift']
|
|
||||||
cc << 'Sources/{after,AnyPromise,GlobalState,dispatch_promise,hang,join,PMKPromise,when,race}.m'
|
|
||||||
cc += hh
|
|
||||||
|
|
||||||
ss.source_files = cc
|
|
||||||
ss.public_header_files = hh
|
|
||||||
ss.preserve_paths = 'Sources/AnyPromise+Private.h', 'Sources/PMKCallVariadicBlock.m', 'Sources/NSMethodSignatureForBlock.m'
|
|
||||||
ss.frameworks = 'Foundation'
|
|
||||||
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'CoreLocation' do |ss|
|
|
||||||
ss.source_files = 'Extensions/CoreLocation/Sources/*'
|
|
||||||
ss.watchos.source_files = 'Extensions/CoreLocation/Sources/CLGeocoder*'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.frameworks = 'CoreLocation'
|
|
||||||
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.watchos.deployment_target = '3.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'EventKit' do |ss|
|
|
||||||
ss.ios.source_files = ss.osx.source_files = ss.watchos.source_files = 'Extensions/EventKit/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.osx.frameworks = ss.watchos.frameworks = 'EventKit'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'Foundation' do |ss|
|
|
||||||
ss.source_files = Dir['Extensions/Foundation/Sources/*']
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.frameworks = 'Foundation'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'HealthKit' do |ss|
|
|
||||||
ss.source_files = Dir['Extensions/HealthKit/Sources/*']
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.frameworks = 'HealthKit'
|
|
||||||
ss.ios.deployment_target = '9.0'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'HomeKit' do |ss|
|
|
||||||
ss.source_files = Dir['Extensions/HomeKit/Sources/*']
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.frameworks = 'HomeKit'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.watchos.deployment_target = '3.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'MapKit' do |ss|
|
|
||||||
ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/MapKit/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'MapKit'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
ss.tvos.deployment_target = '9.2'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'MessageUI' do |ss|
|
|
||||||
ss.ios.source_files = 'Extensions/MessagesUI/Sources/*'
|
|
||||||
ss.ios.frameworks = 'MessageUI'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'OMGHTTPURLRQ' do |ss|
|
|
||||||
ss.source_files = 'Extensions/OMGHTTPURLRQ/Sources/*'
|
|
||||||
ss.dependency 'PromiseKit/Foundation'
|
|
||||||
ss.dependency 'OMGHTTPURLRQ', '~> 3.2'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'Photos' do |ss|
|
|
||||||
ss.ios.source_files = ss.tvos.source_files = ss.osx.source_files = 'Extensions/Photos/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.tvos.frameworks = ss.osx.frameworks = 'Photos'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.13'
|
|
||||||
ss.tvos.deployment_target = '10.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'QuartzCore' do |ss|
|
|
||||||
ss.osx.source_files = ss.ios.source_files = ss.tvos.source_files = 'Extensions/QuartzCore/Sources/*'
|
|
||||||
ss.osx.frameworks = ss.ios.frameworks = ss.tvos.frameworks = 'QuartzCore'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'Social' do |ss|
|
|
||||||
ss.ios.source_files = 'Extensions/Social/Sources/*'
|
|
||||||
ss.osx.source_files = Dir['Extensions/Social/Sources/*'] - ['Categories/Social/Sources/*SLComposeViewController+Promise.swift']
|
|
||||||
ss.ios.frameworks = ss.osx.frameworks = 'Social'
|
|
||||||
ss.dependency 'PromiseKit/Foundation'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'StoreKit' do |ss|
|
|
||||||
ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/StoreKit/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'StoreKit'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'SystemConfiguration' do |ss|
|
|
||||||
ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/SystemConfiguration/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'SystemConfiguration'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.osx.deployment_target = '10.10'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
picker_cc = 'Extensions/UIKit/Sources/UIImagePickerController+Promise.swift'
|
|
||||||
|
|
||||||
s.subspec 'UIKit' do |ss|
|
|
||||||
ss.ios.source_files = ss.tvos.source_files = Dir['Extensions/UIKit/Sources/*'] - [picker_cc]
|
|
||||||
ss.tvos.frameworks = ss.ios.frameworks = 'UIKit'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.tvos.deployment_target = '9.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'UIImagePickerController' do |ss|
|
|
||||||
# Since iOS 10, App Store submissions that contain references to
|
|
||||||
# UIImagePickerController (even if unused in 3rd party libraries)
|
|
||||||
# are rejected unless an Info.plist key is specified, thus we
|
|
||||||
# moved this code to a sub-subspec.
|
|
||||||
#
|
|
||||||
# This *was* a subspec of UIKit, but bizarrely CocoaPods would
|
|
||||||
# include this when specifying *just* UIKit…!
|
|
||||||
|
|
||||||
ss.ios.source_files = picker_cc
|
|
||||||
ss.ios.frameworks = 'UIKit'
|
|
||||||
ss.ios.xcconfig = { "GCC_PREPROCESSOR_DEFINITIONS" => '$(inherited) PMKImagePickerController=1' }
|
|
||||||
ss.dependency 'PromiseKit/UIKit'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
end
|
|
||||||
|
|
||||||
s.subspec 'WatchConnectivity' do |ss|
|
|
||||||
ss.ios.source_files = ss.watchos.source_files = 'Extensions/WatchConnectivity/Sources/*'
|
|
||||||
ss.ios.frameworks = ss.watchos.frameworks = 'WatchConnectivity'
|
|
||||||
ss.dependency 'PromiseKit/CorePromise'
|
|
||||||
ss.ios.deployment_target = '8.0'
|
|
||||||
ss.watchos.deployment_target = '2.0'
|
|
||||||
end
|
|
||||||
end
|
|
@@ -1,29 +0,0 @@
|
|||||||
ignore:
|
|
||||||
- "Tests"
|
|
||||||
- "README.md"
|
|
||||||
- "Documentation"
|
|
||||||
- ".travis.yml"
|
|
||||||
|
|
||||||
codecov:
|
|
||||||
notify:
|
|
||||||
require_ci_to_pass: yes
|
|
||||||
|
|
||||||
coverage:
|
|
||||||
precision: 1
|
|
||||||
round: up
|
|
||||||
range: "70...100"
|
|
||||||
|
|
||||||
status:
|
|
||||||
project: yes
|
|
||||||
patch: yes
|
|
||||||
changes: no
|
|
||||||
|
|
||||||
parsers:
|
|
||||||
gcov:
|
|
||||||
branch_detection:
|
|
||||||
conditional: yes
|
|
||||||
loop: yes
|
|
||||||
method: no
|
|
||||||
macro: no
|
|
||||||
|
|
||||||
comment: off
|
|
@@ -1,12 +0,0 @@
|
|||||||
sources:
|
|
||||||
include:
|
|
||||||
- ../Tests/A+
|
|
||||||
- ../Tests/CorePromise
|
|
||||||
exclude:
|
|
||||||
- ../Tests/A+/0.0.0.swift
|
|
||||||
- ../Tests/CorePromise/Utilities.swift
|
|
||||||
templates:
|
|
||||||
include:
|
|
||||||
- LinuxMain.stencil
|
|
||||||
output:
|
|
||||||
../Tests/LinuxMain.swift
|
|
9
Carthage/Checkouts/PromiseKit/.gitignore
vendored
9
Carthage/Checkouts/PromiseKit/.gitignore
vendored
@@ -1,9 +0,0 @@
|
|||||||
*.xcodeproj/**/xcuserdata/
|
|
||||||
*.xcscmblueprint
|
|
||||||
/Carthage
|
|
||||||
/.build
|
|
||||||
.DS_Store
|
|
||||||
DerivedData
|
|
||||||
/PromiseKit.podspec
|
|
||||||
/Extensions/Carthage
|
|
||||||
/Tests/JS-A+/build
|
|
69
Carthage/Checkouts/PromiseKit/.gitmodules
vendored
69
Carthage/Checkouts/PromiseKit/.gitmodules
vendored
@@ -1,69 +0,0 @@
|
|||||||
[submodule "Extensions/Foundation"]
|
|
||||||
path = Extensions/Foundation
|
|
||||||
url = https://github.com/PromiseKit/Foundation.git
|
|
||||||
[submodule "Extensions/UIKit"]
|
|
||||||
path = Extensions/UIKit
|
|
||||||
url = https://github.com/PromiseKit/UIKit.git
|
|
||||||
[submodule "Extensions/Accounts"]
|
|
||||||
path = Extensions/Accounts
|
|
||||||
url = https://github.com/PromiseKit/Accounts.git
|
|
||||||
[submodule "Extensions/MessagesUI"]
|
|
||||||
path = Extensions/MessagesUI
|
|
||||||
url = https://github.com/PromiseKit/MessagesUI.git
|
|
||||||
[submodule "Extensions/WatchConnectivity"]
|
|
||||||
path = Extensions/WatchConnectivity
|
|
||||||
url = https://github.com/PromiseKit/WatchConnectivity.git
|
|
||||||
[submodule "Extensions/Photos"]
|
|
||||||
path = Extensions/Photos
|
|
||||||
url = https://github.com/PromiseKit/Photos.git
|
|
||||||
[submodule "Extensions/MapKit"]
|
|
||||||
path = Extensions/MapKit
|
|
||||||
url = https://github.com/PromiseKit/MapKit.git
|
|
||||||
[submodule "Extensions/CloudKit"]
|
|
||||||
path = Extensions/CloudKit
|
|
||||||
url = https://github.com/PromiseKit/CloudKit.git
|
|
||||||
[submodule "Extensions/AddressBook"]
|
|
||||||
path = Extensions/AddressBook
|
|
||||||
url = https://github.com/PromiseKit/AddressBook.git
|
|
||||||
[submodule "Extensions/AssetsLibrary"]
|
|
||||||
path = Extensions/AssetsLibrary
|
|
||||||
url = https://github.com/PromiseKit/AssetsLibrary.git
|
|
||||||
[submodule "Extensions/CoreLocation"]
|
|
||||||
path = Extensions/CoreLocation
|
|
||||||
url = https://github.com/PromiseKit/CoreLocation.git
|
|
||||||
[submodule "Extensions/QuartzCore"]
|
|
||||||
path = Extensions/QuartzCore
|
|
||||||
url = https://github.com/PromiseKit/QuartzCore.git
|
|
||||||
[submodule "Extensions/Social"]
|
|
||||||
path = Extensions/Social
|
|
||||||
url = https://github.com/PromiseKit/Social.git
|
|
||||||
[submodule "Extensions/StoreKit"]
|
|
||||||
path = Extensions/StoreKit
|
|
||||||
url = https://github.com/PromiseKit/StoreKit.git
|
|
||||||
[submodule "Extensions/Bolts"]
|
|
||||||
path = Extensions/Bolts
|
|
||||||
url = https://github.com/PromiseKit/Bolts.git
|
|
||||||
[submodule "Extensions/CoreBluetooth"]
|
|
||||||
path = Extensions/CoreBluetooth
|
|
||||||
url = https://github.com/PromiseKit/CoreBluetooth.git
|
|
||||||
[submodule "Extensions/EventKit"]
|
|
||||||
path = Extensions/EventKit
|
|
||||||
url = https://github.com/PromiseKit/EventKit.git
|
|
||||||
[submodule "Extensions/SystemConfiguration"]
|
|
||||||
path = Extensions/SystemConfiguration
|
|
||||||
url = https://github.com/PromiseKit/SystemConfiguration
|
|
||||||
[submodule "Extensions/Alamofire"]
|
|
||||||
path = Extensions/Alamofire
|
|
||||||
url = https://github.com/PromiseKit/Alamofire
|
|
||||||
[submodule "Extensions/OMGHTTPURLRQ"]
|
|
||||||
path = Extensions/OMGHTTPURLRQ
|
|
||||||
url = https://github.com/PromiseKit/OMGHTTPURLRQ
|
|
||||||
[submodule "Extensions/AVFoundation"]
|
|
||||||
path = Extensions/AVFoundation
|
|
||||||
url = https://github.com/PromiseKit/AVFoundation
|
|
||||||
[submodule "Extensions/HomeKit"]
|
|
||||||
path = Extensions/HomeKit
|
|
||||||
url = https://github.com/PromiseKit/HomeKit.git
|
|
||||||
[submodule "Extensions/HealthKit"]
|
|
||||||
path = Extensions/HealthKit
|
|
||||||
url = https://github.com/PromiseKit/PMKHealthKit
|
|
324
Carthage/Checkouts/PromiseKit/.travis.yml
vendored
324
Carthage/Checkouts/PromiseKit/.travis.yml
vendored
@@ -1,324 +0,0 @@
|
|||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- ^\d+\.\d+\.\d+$
|
|
||||||
stages:
|
|
||||||
- lint
|
|
||||||
- compile
|
|
||||||
- test
|
|
||||||
- deploy
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
- &macOS
|
|
||||||
stage: compile
|
|
||||||
osx_image: xcode8.3
|
|
||||||
env: SWIFT=3.1
|
|
||||||
name: macOS / Swift 3.1
|
|
||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
install:
|
|
||||||
xcodebuild -scheme PromiseKit -target PromiseKit SWIFT_VERSION=$SWIFT -quiet SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
script: "true"
|
|
||||||
|
|
||||||
- <<: *macOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=3.2
|
|
||||||
name: macOS / Swift 3.2
|
|
||||||
- <<: *macOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=3.3
|
|
||||||
name: macOS / Swift 3.3
|
|
||||||
- <<: *macOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=3.4
|
|
||||||
name: macOS / Swift 3.4
|
|
||||||
- <<: *macOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=4.0
|
|
||||||
name: macOS / Swift 4.0
|
|
||||||
- <<: *macOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=4.1
|
|
||||||
name: macOS / Swift 4.1
|
|
||||||
- <<: *macOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=4.2
|
|
||||||
name: macOS / Swift 4.2
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
xcodebuild -scheme PromiseKit test -enableCodeCoverage YES
|
|
||||||
after_success:
|
|
||||||
bash <(curl -s https://codecov.io/bash)
|
|
||||||
|
|
||||||
|
|
||||||
- &iOS
|
|
||||||
stage: compile
|
|
||||||
osx_image: xcode8.3
|
|
||||||
env: SWIFT=3.1 DST="OS=10.3.1,name=iPhone SE"
|
|
||||||
name: iOS 10 / Swift 3.1
|
|
||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
install:
|
|
||||||
xcodebuild -scheme PromiseKit -target PromiseKit SWIFT_VERSION=$SWIFT -destination "$DST" -quiet SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
script: "true"
|
|
||||||
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=3.2 DST="OS=11.2,name=iPhone SE"
|
|
||||||
name: iOS 11 / Swift 3.2
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=3.3 DST="OS=11.4,name=iPhone SE"
|
|
||||||
name: iOS 11 / Swift 3.3
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=3.4 DST="OS=12.0,name=iPhone SE"
|
|
||||||
name: iOS 12 / Swift 3.4
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=4.0 DST="OS=11.2,name=iPhone SE"
|
|
||||||
name: iOS 11 / Swift 4.0
|
|
||||||
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode
|
|
||||||
env: SWIFT=4.1 DST="OS=8.4,name=iPhone 4s"
|
|
||||||
name: iOS 8 / Swift 4.1
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=4.1 DST="OS=9.3,name=iPhone 5s"
|
|
||||||
name: iOS 9 / Swift 4.1
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=4.1 DST="OS=10.3.1,name=iPhone SE"
|
|
||||||
name: iOS 10 / Swift 4.1
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=4.1 DST="OS=11.4,name=iPhone SE"
|
|
||||||
name: iOS 11 / Swift 4.1
|
|
||||||
|
|
||||||
- <<: *iOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=4.2 DST="OS=12.0,name=iPhone SE"
|
|
||||||
name: iOS 12 / Swift 4.2
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
xcodebuild -scheme PromiseKit -destination "$DST" test -enableCodeCoverage YES
|
|
||||||
after_success:
|
|
||||||
bash <(curl -s https://codecov.io/bash)
|
|
||||||
|
|
||||||
|
|
||||||
- &tvOS
|
|
||||||
stage: compile
|
|
||||||
name: tvOS 10 / Swift 3.1
|
|
||||||
osx_image: xcode8.3
|
|
||||||
env: SWIFT=3.1 DST="OS=10.2,name=Apple TV 1080p"
|
|
||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
install:
|
|
||||||
xcodebuild -scheme PromiseKit -target PromiseKit SWIFT_VERSION=$SWIFT -destination "$DST" -quiet SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
script: "true"
|
|
||||||
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=3.2 DST="OS=11.2,name=Apple TV"
|
|
||||||
name: tvOS 11 / Swift 3.2
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=3.3 DST="OS=11.4,name=Apple TV"
|
|
||||||
name: tvOS 11 / Swift 3.3
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=3.4 DST="OS=11.4,name=Apple TV"
|
|
||||||
name: tvOS 11 / Swift 3.4
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=4.0 DST="OS=11.2,name=Apple TV"
|
|
||||||
name: tvOS 11 / Swift 4.0
|
|
||||||
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode9.3
|
|
||||||
env: SWIFT=4.1 DST="OS=9.2,name=Apple TV 1080p"
|
|
||||||
name: tvOS 9 / Swift 4.1
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode9.3
|
|
||||||
env: SWIFT=4.1 DST="OS=10.2,name=Apple TV 1080p"
|
|
||||||
name: tvOS 10 / Swift 4.1
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=4.1 DST="OS=11.4,name=Apple TV"
|
|
||||||
name: tvOS 11 / Swift 4.1
|
|
||||||
|
|
||||||
- <<: *tvOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=4.2 DST="OS=12.0,name=Apple TV"
|
|
||||||
name: tvOS 12 / Swift 4.2
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
xcodebuild -scheme PromiseKit -destination "$DST" test -enableCodeCoverage YES
|
|
||||||
after_success:
|
|
||||||
bash <(curl -s https://codecov.io/bash)
|
|
||||||
|
|
||||||
|
|
||||||
- &watchOS
|
|
||||||
stage: compile
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=4.2 DST="OS=5.0,name=Apple Watch Series 3 - 42mm"
|
|
||||||
name: watchOS 5 / Swift 4.2
|
|
||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
script:
|
|
||||||
xcodebuild -scheme PromiseKit SWIFT_VERSION=$SWIFT -destination "$DST" -quiet SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode8.3
|
|
||||||
env: SWIFT=3.1 DST="OS=3.2,name=Apple Watch - 38mm"
|
|
||||||
name: watchOS 3 / Swift 3.1
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=3.2 DST="OS=4.2,name=Apple Watch - 38mm"
|
|
||||||
name: watchOS 4 / Swift 3.2
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=3.3 DST="OS=4.3,name=Apple Watch - 38mm"
|
|
||||||
name: watchOS 4 / Swift 3.3
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=3.4 DST="OS=5.0,name=Apple Watch Series 3 - 42mm"
|
|
||||||
name: watchOS 5 / Swift 3.4
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=4.0 DST="OS=4.2,name=Apple Watch - 38mm"
|
|
||||||
name: watchOS 4 / Swift 4.0
|
|
||||||
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode9.3
|
|
||||||
env: SWIFT=4.1 DST="OS=2.2,name=Apple Watch - 38mm"
|
|
||||||
name: watchOS 2 / Swift 4.1
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode9.3
|
|
||||||
env: SWIFT=4.1 DST="OS=3.2,name=Apple Watch - 38mm"
|
|
||||||
name: watchOS 3 / Swift 4.1
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=4.1 DST="OS=4.3,name=Apple Watch - 38mm"
|
|
||||||
name: watchOS 4 / Swift 4.1
|
|
||||||
|
|
||||||
- <<: *watchOS
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=4.2 DST="OS=5.0,name=Apple Watch Series 3 - 42mm"
|
|
||||||
name: watchOS 5 / Swift 4.2
|
|
||||||
|
|
||||||
|
|
||||||
- &pod
|
|
||||||
stage: lint
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=4.2
|
|
||||||
name: pod lib lint --swift-version=4.2
|
|
||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
before_install: |
|
|
||||||
mv .github/PromiseKit.podspec .
|
|
||||||
gem install cocoapods --prerelease --version 1.6.0.beta.1
|
|
||||||
script:
|
|
||||||
pod lib lint --subspec=PromiseKit/CorePromise --fail-fast --swift-version=$SWIFT
|
|
||||||
|
|
||||||
- <<: *pod
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=4.1
|
|
||||||
name: pod lib lint --swift-version=4.1
|
|
||||||
- <<: *pod
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=4.0
|
|
||||||
name: pod lib lint --swift-version=4.0
|
|
||||||
- <<: *pod
|
|
||||||
osx_image: xcode10
|
|
||||||
env: SWIFT=3.4
|
|
||||||
name: pod lib lint --swift-version=3.4
|
|
||||||
- <<: *pod
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: SWIFT=3.3
|
|
||||||
name: pod lib lint --swift-version=3.3
|
|
||||||
- <<: *pod
|
|
||||||
osx_image: xcode9.2
|
|
||||||
env: SWIFT=3.2
|
|
||||||
name: pod lib lint --swift-version=3.2
|
|
||||||
- <<: *pod
|
|
||||||
osx_image: xcode8.3
|
|
||||||
env: SWIFT=3.1
|
|
||||||
name: pod lib lint --swift-version=3.1
|
|
||||||
|
|
||||||
|
|
||||||
- &linux
|
|
||||||
stage: compile
|
|
||||||
env: SWIFT_BUILD_VERSION=3 SWIFT_VERSION=4.0.3
|
|
||||||
name: Linux / Swift 3.2
|
|
||||||
os: linux
|
|
||||||
dist: trusty
|
|
||||||
sudo: required
|
|
||||||
language: generic
|
|
||||||
before_install:
|
|
||||||
eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
|
|
||||||
install:
|
|
||||||
swift build -Xswiftc -swift-version -Xswiftc $SWIFT_BUILD_VERSION
|
|
||||||
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_BUILD_VERSION=3 SWIFT_VERSION=4.1.2
|
|
||||||
name: Linux / Swift 3.3
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_BUILD_VERSION=3 SWIFT_VERSION=4.2
|
|
||||||
name: Linux / Swift 3.4
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_BUILD_VERSION=4 SWIFT_VERSION=4.0.3
|
|
||||||
name: Linux / Swift 4.0
|
|
||||||
stage: test
|
|
||||||
install: swift test -Xswiftc -swift-version -Xswiftc 4
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_BUILD_VERSION=4 SWIFT_VERSION=4.1.2
|
|
||||||
name: Linux / Swift 4.1
|
|
||||||
stage: test
|
|
||||||
install: swift test -Xswiftc -swift-version -Xswiftc 4
|
|
||||||
- <<: *linux
|
|
||||||
env: SWIFT_BUILD_VERSION=4 SWIFT_VERSION=4.2
|
|
||||||
name: Linux / Swift 4.2
|
|
||||||
stage: test
|
|
||||||
install: swift test -Xswiftc -swift-version -Xswiftc 4
|
|
||||||
|
|
||||||
|
|
||||||
# only run one instance of these since they test behavior
|
|
||||||
- stage: test
|
|
||||||
name: Promises/A+ via Javascript Bridge
|
|
||||||
language: objective-c
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode10
|
|
||||||
before_install:
|
|
||||||
npm install -g npm
|
|
||||||
# ^^ need newer npm than comes with the image
|
|
||||||
install: |
|
|
||||||
cd Tests/JS-A+
|
|
||||||
set -e
|
|
||||||
npm ci
|
|
||||||
npm run build
|
|
||||||
set +e
|
|
||||||
# ^^ `cd` on travis returns a non-zero exit code!
|
|
||||||
cd ../..
|
|
||||||
xcodebuild -scheme PromiseKit -quiet SWIFT_VERSION=4.2 SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
script:
|
|
||||||
xcodebuild -scheme PromiseKit SWIFT_VERSION=4.2 test
|
|
||||||
# TODO only run the A+ tests
|
|
||||||
# TODO shouldn’t build twice! Be kind to Travis.
|
|
||||||
cache:
|
|
||||||
- Tests/JS-A+/build
|
|
||||||
- Tests/JS-A+/node_modules
|
|
||||||
|
|
||||||
|
|
||||||
- stage: deploy
|
|
||||||
if: tag IS present
|
|
||||||
script: |
|
|
||||||
set -euxo pipefail
|
|
||||||
pod trunk push --verbose --swift-version=4.2 | ruby -e 'ARGF.each{ print "." }'
|
|
||||||
# This pipe because Travis times us out if there is no output
|
|
||||||
# AND `pod` defaults to hardly any output
|
|
||||||
# BUT `--verbose` generates so much output that Travis kills our script due to *too much* output!
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode10
|
|
||||||
language: objective-c
|
|
@@ -1,211 +0,0 @@
|
|||||||
# Common Misusage
|
|
||||||
|
|
||||||
## Doubling up Promises
|
|
||||||
|
|
||||||
Don’t do this:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func toggleNetworkSpinnerWithPromise<T>(funcToCall: () -> Promise<T>) -> Promise<T> {
|
|
||||||
return Promise { seal in
|
|
||||||
firstly {
|
|
||||||
setNetworkActivityIndicatorVisible(true)
|
|
||||||
return funcToCall()
|
|
||||||
}.then { result in
|
|
||||||
seal.fulfill(result)
|
|
||||||
}.always {
|
|
||||||
setNetworkActivityIndicatorVisible(false)
|
|
||||||
}.catch { err in
|
|
||||||
seal.reject(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Do this:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func toggleNetworkSpinnerWithPromise<T>(funcToCall: () -> Promise<T>) -> Promise<T> {
|
|
||||||
return firstly {
|
|
||||||
setNetworkActivityIndicatorVisible(true)
|
|
||||||
return funcToCall()
|
|
||||||
}.always {
|
|
||||||
setNetworkActivityIndicatorVisible(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You already *had* a promise, you don’t need to wrap it in another promise.
|
|
||||||
|
|
||||||
|
|
||||||
## Optionals in Promises
|
|
||||||
|
|
||||||
When we see `Promise<Item?>`, it usually implies a misuse of promises. For
|
|
||||||
example:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
return firstly {
|
|
||||||
getItems()
|
|
||||||
}.then { items -> Promise<[Item]?> in
|
|
||||||
guard !items.isEmpty else {
|
|
||||||
return .value(nil)
|
|
||||||
}
|
|
||||||
return Promise(value: items)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The second `then` chooses to return `nil` in some circumstances. This choice
|
|
||||||
imposes the need to check for `nil` on the consumer of the promise.
|
|
||||||
|
|
||||||
It's usually better to shunt these sorts of exceptions away from the
|
|
||||||
happy path and onto the error path. In this case, we can create a specific
|
|
||||||
error type for this condition:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
return firstly {
|
|
||||||
getItems()
|
|
||||||
}.map { items -> [Item]> in
|
|
||||||
guard !items.isEmpty else {
|
|
||||||
throw MyError.emptyItems
|
|
||||||
}
|
|
||||||
return items
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> *Note*: Use `compactMap` when an API outside your control returns an Optional and you want to generate an error instead of propagating `nil`.
|
|
||||||
|
|
||||||
# Tips n’ Tricks
|
|
||||||
|
|
||||||
## Background-Loaded Member Variables
|
|
||||||
|
|
||||||
```swift
|
|
||||||
class MyViewController: UIViewController {
|
|
||||||
private let ambience: Promise<AVAudioPlayer> = DispatchQueue.global().async(.promise) {
|
|
||||||
guard let asset = NSDataAsset(name: "CreepyPad") else { throw PMKError.badInput }
|
|
||||||
let player = try AVAudioPlayer(data: asset.data)
|
|
||||||
player.prepareToPlay()
|
|
||||||
return player
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Chaining Animations
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
UIView.animate(.promise, duration: 0.3) {
|
|
||||||
self.button1.alpha = 0
|
|
||||||
}
|
|
||||||
}.then {
|
|
||||||
UIView.animate(.promise, duration: 0.3) {
|
|
||||||
self.button2.alpha = 1
|
|
||||||
}
|
|
||||||
}.then {
|
|
||||||
UIView.animate(.promise, duration: 0.3) {
|
|
||||||
adjustConstraints()
|
|
||||||
self.view.layoutIfNeeded()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Voiding Promises
|
|
||||||
|
|
||||||
It is often convenient to erase the type of a promise to facilitate chaining.
|
|
||||||
For example, `UIView.animate(.promise)` returns `Guarantee<Bool>` because UIKit’s
|
|
||||||
completion API supplies a `Bool`. However, we usually don’t need this value and
|
|
||||||
can chain more simply if it is discarded (that is, converted to `Void`). We can use
|
|
||||||
`asVoid()` to achieve this conversion:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
UIView.animate(.promise, duration: 0.3) {
|
|
||||||
self.button1.alpha = 0
|
|
||||||
}.asVoid().done(self.nextStep)
|
|
||||||
```
|
|
||||||
|
|
||||||
For situations in which we are combining many promises into a `when`, `asVoid()`
|
|
||||||
becomes essential:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
let p1 = foo()
|
|
||||||
let p2 = bar()
|
|
||||||
let p3 = baz()
|
|
||||||
//…
|
|
||||||
let p10 = fluff()
|
|
||||||
|
|
||||||
when(fulfilled: p1.asVoid(), p2.asVoid(), /*…*/, p10.asVoid()).then {
|
|
||||||
let value1 = p1.value! // safe bang since all the promises fulfilled
|
|
||||||
// …
|
|
||||||
let value10 = p10.value!
|
|
||||||
}.catch {
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You normally don't have to do this explicitly because `when` does it for you
|
|
||||||
for up to 5 parameters.
|
|
||||||
|
|
||||||
|
|
||||||
## Blocking (Await)
|
|
||||||
|
|
||||||
Sometimes you have to block the main thread to await completion of an asynchronous task.
|
|
||||||
In these cases, you can (with caution) use `wait`:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
public extension UNUserNotificationCenter {
|
|
||||||
var wasPushRequested: Bool {
|
|
||||||
let settings = Guarantee(resolver: getNotificationSettings).wait()
|
|
||||||
return settings != .notDetermined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The task under the promise **must not** call back onto the current thread or it
|
|
||||||
will deadlock.
|
|
||||||
|
|
||||||
## Starting a Chain on a Background Queue/Thread
|
|
||||||
|
|
||||||
`firstly` deliberately does not take a queue. A detailed rationale for this choice
|
|
||||||
can be found in the ticket tracker.
|
|
||||||
|
|
||||||
So, if you want to start a chain by dispatching to the background, you have to use
|
|
||||||
`DispatchQueue.async`:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
DispatchQueue.global().async(.promise) {
|
|
||||||
return value
|
|
||||||
}.done { value in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
However, this function cannot return a promise because of Swift compiler ambiguity
|
|
||||||
issues. Thus, if you must start a promise on a background queue, you need to
|
|
||||||
do something like this:
|
|
||||||
|
|
||||||
|
|
||||||
```swift
|
|
||||||
Promise { seal in
|
|
||||||
DispatchQueue.global().async {
|
|
||||||
seal(value)
|
|
||||||
}
|
|
||||||
}.done { value in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Or more simply (though with caveats; see the documentation for `wait`):
|
|
||||||
|
|
||||||
```swift
|
|
||||||
DispatchQueue.global().async(.promise) {
|
|
||||||
return try fetch().wait()
|
|
||||||
}.done { value in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
However, you shouldn't need to do this often. If you find yourself wanting to use
|
|
||||||
this technique, perhaps you should instead modify the code for `fetch` to make it do
|
|
||||||
its work on a background thread.
|
|
||||||
|
|
||||||
Promises abstract asynchronicity, so exploit and support that model. Design your
|
|
||||||
APIs so that consumers don’t have to care what queue your functions run on.
|
|
@@ -1,480 +0,0 @@
|
|||||||
# Common Patterns
|
|
||||||
|
|
||||||
One feature of promises that makes them particularly useful is that they are composable.
|
|
||||||
This fact enables complex, yet safe asynchronous patterns that would otherwise be quite
|
|
||||||
intimidating when implemented with traditional methods.
|
|
||||||
|
|
||||||
|
|
||||||
## Chaining
|
|
||||||
|
|
||||||
The most common pattern is chaining:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
fetch()
|
|
||||||
}.then {
|
|
||||||
map($0)
|
|
||||||
}.then {
|
|
||||||
set($0)
|
|
||||||
return animate()
|
|
||||||
}.ensure {
|
|
||||||
cleanup()
|
|
||||||
}.catch {
|
|
||||||
handle(error: $0)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you return a promise in a `then`, the next `then` *waits* on that promise
|
|
||||||
before continuing. This is the essence of promises.
|
|
||||||
|
|
||||||
Promises are easy to compose, so they encourage you to develop highly asynchronous
|
|
||||||
apps without fear of the spaghetti code (and associated refactoring pains) of
|
|
||||||
asynchronous systems that use completion handlers.
|
|
||||||
|
|
||||||
|
|
||||||
## APIs That Use Promises
|
|
||||||
|
|
||||||
Promises are composable, so return them instead of accepting completion blocks:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
class MyRestAPI {
|
|
||||||
func user() -> Promise<User> {
|
|
||||||
return firstly {
|
|
||||||
URLSession.shared.dataTask(.promise, with: url)
|
|
||||||
}.compactMap {
|
|
||||||
try JSONSerialization.jsonObject(with: $0.data) as? [String: Any]
|
|
||||||
}.map { dict in
|
|
||||||
User(dict: dict)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func avatar() -> Promise<UIImage> {
|
|
||||||
return user().then { user in
|
|
||||||
URLSession.shared.dataTask(.promise, with: user.imageUrl)
|
|
||||||
}.compactMap {
|
|
||||||
UIImage(data: $0.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This way, asynchronous chains can cleanly and seamlessly incorporate code from all over
|
|
||||||
your app without violating architectural boundaries.
|
|
||||||
|
|
||||||
> *Note*: We provide [promises for Alamofire](https://github.com/PromiseKit/Alamofire-) too!
|
|
||||||
|
|
||||||
|
|
||||||
## Background Work
|
|
||||||
|
|
||||||
```swift
|
|
||||||
class MyRestAPI {
|
|
||||||
func avatar() -> Promise<UIImage> {
|
|
||||||
let bgq = DispatchQueue.global(qos: .userInitiated)
|
|
||||||
|
|
||||||
return firstly {
|
|
||||||
user()
|
|
||||||
}.then(on: bgq) { user in
|
|
||||||
URLSession.shared.dataTask(.promise, with: user.imageUrl)
|
|
||||||
}.compactMap(on: bgq) {
|
|
||||||
UIImage(data: $0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
All PromiseKit handlers take an `on` parameter that lets you designate the dispatch queue
|
|
||||||
on which to run the handler. The default is always the main queue.
|
|
||||||
|
|
||||||
PromiseKit is *entirely* thread safe.
|
|
||||||
|
|
||||||
> *Tip*: With caution, you can have all `then`, `map`, `compactMap`, etc., run on
|
|
||||||
a background queue. See `PromiseKit.conf`. Note that we suggest only changing
|
|
||||||
the queue for the `map` suite of functions, so `done` and `catch` will
|
|
||||||
continue to run on the main queue, which is *usually* what you want.
|
|
||||||
|
|
||||||
## Failing Chains
|
|
||||||
|
|
||||||
If an error occurs mid-chain, simply throw an error:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
foo()
|
|
||||||
}.then { baz in
|
|
||||||
bar(baz)
|
|
||||||
}.then { result in
|
|
||||||
guard !result.isBad else { throw MyError.myIssue }
|
|
||||||
//…
|
|
||||||
return doOtherThing()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The error will surface at the next `catch` handler.
|
|
||||||
|
|
||||||
Since promises handle thrown errors, you don't have to wrap calls to throwing functions
|
|
||||||
in a `do` block unless you really want to handle the errors locally:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
foo().then { baz in
|
|
||||||
bar(baz)
|
|
||||||
}.then { result in
|
|
||||||
try doOtherThing()
|
|
||||||
}.catch { error in
|
|
||||||
// if doOtherThing() throws, we end up here
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> *Tip*: Swift lets you define an inline `enum Error` inside the function you
|
|
||||||
are working on. This isn’t *great* coding practice, but it's better than
|
|
||||||
avoiding throwing an error because you couldn't be bothered to define a good global
|
|
||||||
`Error` `enum`.
|
|
||||||
|
|
||||||
|
|
||||||
## Abstracting Away Asychronicity
|
|
||||||
|
|
||||||
```swift
|
|
||||||
var fetch = API.fetch()
|
|
||||||
|
|
||||||
override func viewDidAppear() {
|
|
||||||
fetch.then { items in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func buttonPressed() {
|
|
||||||
fetch.then { items in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func refresh() {
|
|
||||||
// ensure only one fetch operation happens at a time
|
|
||||||
|
|
||||||
if fetch.isResolved {
|
|
||||||
startSpinner()
|
|
||||||
fetch = API.fetch().ensure {
|
|
||||||
stopSpinner()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fetch
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
With promises, you don’t need to worry about *when* your asynchronous operation
|
|
||||||
finishes. Just act like it already has.
|
|
||||||
|
|
||||||
Above, we see that you can call `then` as many times on a promise as you
|
|
||||||
like. All the blocks will be executed in the order they were added.
|
|
||||||
|
|
||||||
|
|
||||||
## Chaining Sequences
|
|
||||||
|
|
||||||
When you have a series of tasks to perform on an array of data:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// fade all visible table cells one by one in a “cascading” effect
|
|
||||||
|
|
||||||
let fade = Guarantee()
|
|
||||||
for cell in tableView.visibleCells {
|
|
||||||
fade = fade.then {
|
|
||||||
UIView.animate(.promise, duration: 0.1) {
|
|
||||||
cell.alpha = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fade.done {
|
|
||||||
// finish
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> *Note*: You *usually* you want `when()`, since `when` executes all of its
|
|
||||||
component promises in parallel and so completes much faster. Use the pattern
|
|
||||||
shown above in situations where tasks *must* be run sequentially; animation
|
|
||||||
is a good example.
|
|
||||||
|
|
||||||
We also provide `when(concurrently:)`, which lets you schedule more than
|
|
||||||
one promise at a time if you need to.
|
|
||||||
|
|
||||||
## Timeout
|
|
||||||
|
|
||||||
```swift
|
|
||||||
let fetches: [Promise<T>] = makeFetches()
|
|
||||||
let timeout = after(seconds: 4)
|
|
||||||
|
|
||||||
race(when(fulfilled: fetches).asVoid(), timeout).then {
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`race` continues as soon as one of the promises it is watching finishes.
|
|
||||||
|
|
||||||
Make sure the promises you pass to `race` are all of the same type. The easiest way
|
|
||||||
to ensure this is to use `asVoid()`.
|
|
||||||
|
|
||||||
Note that if any component promise rejects, the `race` will reject, too.
|
|
||||||
|
|
||||||
|
|
||||||
# Minimum Duration
|
|
||||||
|
|
||||||
Sometimes you need a task to take *at least* a certain amount of time. (For example,
|
|
||||||
you want to show a progress spinner, but if it shows for less than 0.3 seconds, the UI
|
|
||||||
appears broken to the user.)
|
|
||||||
|
|
||||||
```swift
|
|
||||||
let waitAtLeast = after(seconds: 0.3)
|
|
||||||
|
|
||||||
firstly {
|
|
||||||
foo()
|
|
||||||
}.then {
|
|
||||||
waitAtLeast
|
|
||||||
}.done {
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The code above works because we create the delay *before* we do work in `foo()`. By the
|
|
||||||
time we get to waiting on that promise, either it will have already timed out or we will wait
|
|
||||||
for whatever remains of the 0.3 seconds before continuing the chain.
|
|
||||||
|
|
||||||
|
|
||||||
## Cancellation
|
|
||||||
|
|
||||||
Promises don’t have a `cancel` function, but they do support cancellation through a
|
|
||||||
special error type that conforms to the `CancellableError` protocol.
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func foo() -> (Promise<Void>, cancel: () -> Void) {
|
|
||||||
let task = Task(…)
|
|
||||||
var cancelme = false
|
|
||||||
|
|
||||||
let promise = Promise<Void> { seal in
|
|
||||||
task.completion = { value in
|
|
||||||
guard !cancelme else { return reject(PMKError.cancelled) }
|
|
||||||
seal.fulfill(value)
|
|
||||||
}
|
|
||||||
task.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
let cancel = {
|
|
||||||
cancelme = true
|
|
||||||
task.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
return (promise, cancel)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Promises don’t have a `cancel` function because you don’t want code outside of
|
|
||||||
your control to be able to cancel your operations--*unless*, of course, you explicitly
|
|
||||||
want to enable that behavior. In cases where you do want cancellation, the exact way
|
|
||||||
that it should work will vary depending on how the underlying task supports cancellation.
|
|
||||||
PromiseKit provides cancellation primitives but no concrete API.
|
|
||||||
|
|
||||||
Cancelled chains do not call `catch` handlers by default. However you can
|
|
||||||
intercept cancellation if you like:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
foo.then {
|
|
||||||
//…
|
|
||||||
}.catch(policy: .allErrors) {
|
|
||||||
// cancelled errors are handled *as well*
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Important**: Canceling a promise chain is *not* the same as canceling the underlying
|
|
||||||
asynchronous task. Promises are wrappers around asynchronicity, but they have no
|
|
||||||
control over the underlying tasks. If you need to cancel an underlying task, you
|
|
||||||
need to cancel the underlying task!
|
|
||||||
|
|
||||||
> The library [CancellablePromiseKit](https://github.com/johannesd/CancellablePromiseKit) extends the concept of Promises to fully cover cancellable tasks.
|
|
||||||
|
|
||||||
## Retry / Polling
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func attempt<T>(maximumRetryCount: Int = 3, delayBeforeRetry: DispatchTimeInterval = .seconds(2), _ body: @escaping () -> Promise<T>) -> Promise<T> {
|
|
||||||
var attempts = 0
|
|
||||||
func attempt() -> Promise<T> {
|
|
||||||
attempts += 1
|
|
||||||
return body().recover { error -> Promise<T> in
|
|
||||||
guard attempts < maximumRetryCount else { throw error }
|
|
||||||
return after(delayBeforeRetry).then(on: nil, attempt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return attempt()
|
|
||||||
}
|
|
||||||
|
|
||||||
attempt(maximumRetryCount: 3) {
|
|
||||||
flakeyTask(parameters: foo)
|
|
||||||
}.then {
|
|
||||||
//…
|
|
||||||
}.catch { _ in
|
|
||||||
// we attempted three times but still failed
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In most cases, you should probably supplement the code above so that it re-attempts only for
|
|
||||||
specific error conditions.
|
|
||||||
|
|
||||||
|
|
||||||
## Wrapping Delegate Systems
|
|
||||||
|
|
||||||
Be careful with Promises and delegate systems, as they are not always compatible.
|
|
||||||
Promises complete *once*, whereas most delegate systems may notify their delegate many
|
|
||||||
times. This is why, for example, there is no PromiseKit extension for a
|
|
||||||
`UIButton`.
|
|
||||||
|
|
||||||
A good example of an appropriate time to wrap delegation is when you need a
|
|
||||||
single `CLLocation` lookup:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
extension CLLocationManager {
|
|
||||||
static func promise() -> Promise<CLLocation> {
|
|
||||||
return PMKCLLocationManagerProxy().promise
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PMKCLLocationManagerProxy: NSObject, CLLocationManagerDelegate {
|
|
||||||
private let (promise, seal) = Promise<[CLLocation]>.pending()
|
|
||||||
private var retainCycle: PMKCLLocationManagerProxy?
|
|
||||||
private let manager = CLLocationManager()
|
|
||||||
|
|
||||||
init() {
|
|
||||||
super.init()
|
|
||||||
retainCycle = self
|
|
||||||
manager.delegate = self // does not retain hence the `retainCycle` property
|
|
||||||
|
|
||||||
promise.ensure {
|
|
||||||
// ensure we break the retain cycle
|
|
||||||
self.retainCycle = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc fileprivate func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
|
||||||
seal.fulfill(locations)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func locationManager(_: CLLocationManager, didFailWithError error: Error) {
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use:
|
|
||||||
|
|
||||||
CLLocationManager.promise().then { locations in
|
|
||||||
//…
|
|
||||||
}.catch { error in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> Please note: we provide this promise with our CoreLocation extensions at
|
|
||||||
> https://github.com/PromiseKit/CoreLocation
|
|
||||||
|
|
||||||
|
|
||||||
## Recovery
|
|
||||||
|
|
||||||
Sometimes you don’t want an error to cascade. Instead, you want to supply a default result:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
CLLocationManager.requestLocation().recover { error -> Promise<CLLocation> in
|
|
||||||
guard error == MyError.airplaneMode else {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
return .value(CLLocation.savannah)
|
|
||||||
}.done { location in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Be careful not to ignore all errors, though! Recover only those errors that make sense to recover.
|
|
||||||
|
|
||||||
|
|
||||||
## Promises for Modal View Controllers
|
|
||||||
|
|
||||||
```swift
|
|
||||||
class ViewController: UIViewController {
|
|
||||||
|
|
||||||
private let (promise, seal) = Guarantee<…>.pending() // use Promise if your flow can fail
|
|
||||||
|
|
||||||
func show(in: UIViewController) -> Promise<…> {
|
|
||||||
in.show(self, sender: in)
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
|
|
||||||
func done() {
|
|
||||||
dismiss(animated: true)
|
|
||||||
seal.fulfill(…)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use:
|
|
||||||
|
|
||||||
ViewController().show(in: self).done {
|
|
||||||
//…
|
|
||||||
}.catch { error in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This is the best approach we have found, which is a pity as it requires the
|
|
||||||
presentee to control the presentation and requires the presentee to dismiss itself
|
|
||||||
explicitly.
|
|
||||||
|
|
||||||
Nothing seems to beat storyboard segues for decoupling an app's controllers.
|
|
||||||
|
|
||||||
|
|
||||||
## Saving Previous Results
|
|
||||||
|
|
||||||
Let’s say you have:
|
|
||||||
|
|
||||||
|
|
||||||
```swift
|
|
||||||
login().then { username in
|
|
||||||
fetch(avatar: username)
|
|
||||||
}.done { image in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
What if you want access to both `username` and `image` in your `done`?
|
|
||||||
|
|
||||||
The most obvious way is to use nesting:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
login().then { username in
|
|
||||||
fetch(avatar: username).done { image in
|
|
||||||
// we have access to both `image` and `username`
|
|
||||||
}
|
|
||||||
}.done {
|
|
||||||
// the chain still continues as you'd expect
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
However, such nesting reduces the clarity of the chain. Instead, we could use Swift
|
|
||||||
tuples:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
login().then { username in
|
|
||||||
fetch(avatar: username).map { ($0, username) }
|
|
||||||
}.then { image, username in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The code above simply maps `Promise<String>` into `Promise<(UIImage, String)>`.
|
|
||||||
|
|
||||||
|
|
||||||
## Waiting on Multiple Promises, Whatever Their Result
|
|
||||||
|
|
||||||
Use `when(resolved:)`:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
when(resolved: a, b).done { (results: [Result<T>]) in
|
|
||||||
// `Result` is an enum of `.fulfilled` or `.rejected`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ^^ cannot call `catch` as `when(resolved:)` returns a `Guarantee`
|
|
||||||
```
|
|
||||||
|
|
||||||
Generally, you don't want this! People ask for it a lot, but usually because
|
|
||||||
they are trying to ignore errors. What they really need is to use `recover` on one of the
|
|
||||||
promises. Errors happen, so they should be handled; you usually don't want to ignore them.
|
|
@@ -1,131 +0,0 @@
|
|||||||
# Image Cache with Promises
|
|
||||||
|
|
||||||
Here is an example of a simple image cache that uses promises to simplify the
|
|
||||||
state machine:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
import Foundation
|
|
||||||
import PromiseKit
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Small (10 images)
|
|
||||||
* Thread-safe
|
|
||||||
* Consolidates multiple requests to the same URLs
|
|
||||||
* Removes stale entries (FIXME well, strictly we may delete while fetching from cache, but this is unlikely and non-fatal)
|
|
||||||
* Completely _ignores_ server caching headers!
|
|
||||||
*/
|
|
||||||
|
|
||||||
private let q = DispatchQueue(label: "org.promisekit.cache.image")
|
|
||||||
private var active: [URL: Promise<Data>] = [:]
|
|
||||||
private var cleanup = Promise()
|
|
||||||
|
|
||||||
|
|
||||||
public func fetch(image url: URL) -> Promise<Data> {
|
|
||||||
var promise: Promise<Data>?
|
|
||||||
q.sync {
|
|
||||||
promise = active[url]
|
|
||||||
}
|
|
||||||
if let promise = promise {
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
|
|
||||||
q.sync(flags: .barrier) {
|
|
||||||
promise = Promise(.start) {
|
|
||||||
|
|
||||||
let dst = try url.cacheDestination()
|
|
||||||
|
|
||||||
guard !FileManager.default.isReadableFile(atPath: dst.path) else {
|
|
||||||
return Promise(dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise { seal in
|
|
||||||
URLSession.shared.downloadTask(with: url) { tmpurl, _, error in
|
|
||||||
do {
|
|
||||||
guard let tmpurl = tmpurl else { throw error ?? E.unexpectedError }
|
|
||||||
try FileManager.default.moveItem(at: tmpurl, to: dst)
|
|
||||||
seal.fulfill(dst)
|
|
||||||
} catch {
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}.resume()
|
|
||||||
}
|
|
||||||
|
|
||||||
}.then(on: .global(QoS: .userInitiated)) {
|
|
||||||
try Data(contentsOf: $0)
|
|
||||||
}
|
|
||||||
|
|
||||||
active[url] = promise
|
|
||||||
|
|
||||||
if cleanup.isFulfilled {
|
|
||||||
cleanup = promise!.asVoid().then(on: .global(QoS: .utility), execute: docleanup)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise!
|
|
||||||
}
|
|
||||||
|
|
||||||
public func cached(image url: URL) -> Data? {
|
|
||||||
guard let dst = try? url.cacheDestination() else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return try? Data(contentsOf: dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public func cache(destination remoteUrl: URL) throws -> URL {
|
|
||||||
return try remoteUrl.cacheDestination()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func cache() throws -> URL {
|
|
||||||
guard let dst = FileManager.default.docs?
|
|
||||||
.appendingPathComponent("Library")
|
|
||||||
.appendingPathComponent("Caches")
|
|
||||||
.appendingPathComponent("cache.img")
|
|
||||||
else {
|
|
||||||
throw E.unexpectedError
|
|
||||||
}
|
|
||||||
|
|
||||||
try FileManager.default.createDirectory(at: dst, withIntermediateDirectories: true, attributes: [:])
|
|
||||||
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension URL {
|
|
||||||
func cacheDestination() throws -> URL {
|
|
||||||
|
|
||||||
var fn = String(hashValue)
|
|
||||||
let ext = pathExtension
|
|
||||||
|
|
||||||
// many of Apple's functions don’t recognize file type
|
|
||||||
// unless we preserve the file extension
|
|
||||||
if !ext.isEmpty {
|
|
||||||
fn += ".\(ext)"
|
|
||||||
}
|
|
||||||
|
|
||||||
return try cache().appendingPathComponent(fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum E: Error {
|
|
||||||
case unexpectedError
|
|
||||||
case noCreationTime
|
|
||||||
}
|
|
||||||
|
|
||||||
private func docleanup() throws {
|
|
||||||
var contents = try FileManager.default
|
|
||||||
.contentsOfDirectory(at: try cache(), includingPropertiesForKeys: [.creationDateKey])
|
|
||||||
.map { url -> (Date, URL) in
|
|
||||||
guard let date = try url.resourceValues(forKeys: [.creationDateKey]).creationDate else {
|
|
||||||
throw E.noCreationTime
|
|
||||||
}
|
|
||||||
return (date, url)
|
|
||||||
}.sorted(by: {
|
|
||||||
$0.0 > $1.0
|
|
||||||
})
|
|
||||||
|
|
||||||
while contents.count > 10 {
|
|
||||||
let rm = contents.popLast()!.1
|
|
||||||
try FileManager.default.removeItem(at: rm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
````
|
|
@@ -1,20 +0,0 @@
|
|||||||
Promise(.pending) { seal in
|
|
||||||
URLSession.shared.dataTask(with: rq, completionHandler: { data, rsp, error in
|
|
||||||
if let data = data {
|
|
||||||
seal.fulfill(data)
|
|
||||||
} else if let error = error {
|
|
||||||
if case URLError.badServerResponse = error, let rsp = rsp as? HTTPURLResponse {
|
|
||||||
seal.reject(Error.badResponse(rsp.statusCode))
|
|
||||||
} else {
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
seal.reject(PMKError.invalidCallingConvention)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Error: Swift.Error {
|
|
||||||
case badUrl
|
|
||||||
case badResponse(Int)
|
|
||||||
}
|
|
375
Carthage/Checkouts/PromiseKit/Documentation/FAQ.md
vendored
375
Carthage/Checkouts/PromiseKit/Documentation/FAQ.md
vendored
@@ -1,375 +0,0 @@
|
|||||||
# FAQ
|
|
||||||
|
|
||||||
## Why should I use PromiseKit over X-Promises-Foo?
|
|
||||||
|
|
||||||
* PromiseKit has a heavy focus on **developer experience**. You’re a developer; do you care about your experience? Yes? Then pick PromiseKit.
|
|
||||||
* Do you care about having any bugs you find fixed? Then pick PromiseKit.
|
|
||||||
* Do you care about having your input heard and reacted to in a fast fashion? Then pick PromiseKit.
|
|
||||||
* Do you want a library that has been maintained continuously and passionately for 6 years? Then pick PromiseKit.
|
|
||||||
* Do you want a library that the community has chosen to be their №1 Promises/Futures library? Then pick PromiseKit.
|
|
||||||
* Do you want to be able to use Promises with Apple’s SDKs rather than having to do all the work of writing the Promise implementations yourself? Then pick PromiseKit.
|
|
||||||
* Do you want to be able to use Promises with Swift 3.x, Swift 4.x, ObjC, iOS, tvOS, watchOS, macOS, Android & Linux? Then pick PromiseKit.
|
|
||||||
* PromiseKit verifies its correctness by testing against the entire [Promises/A+ test suite](https://github.com/promises-aplus/promises-tests).
|
|
||||||
|
|
||||||
## How do I create a fulfilled `Void` promise?
|
|
||||||
|
|
||||||
```swift
|
|
||||||
let foo = Promise()
|
|
||||||
|
|
||||||
// or:
|
|
||||||
|
|
||||||
let bar = Promise.value(())
|
|
||||||
```
|
|
||||||
|
|
||||||
## How do I “early `return`”?
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func foo() -> Promise<Void> {
|
|
||||||
guard thingy else {
|
|
||||||
return Promise()
|
|
||||||
}
|
|
||||||
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
|
|
||||||
func bar() -> Promise<SomethingNotVoid> {
|
|
||||||
guard thingy else {
|
|
||||||
return .value(instanceOfSomethingNotVoid)
|
|
||||||
}
|
|
||||||
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Do I need to worry about retain cycles?
|
|
||||||
|
|
||||||
Generally, no. Once a promise completes, all handlers are released and so
|
|
||||||
any references to `self` are also released.
|
|
||||||
|
|
||||||
However, if your chain contains side effects that you would typically
|
|
||||||
not want to happen after, say, a view controller is popped, then you should still
|
|
||||||
use `weak self` (and check for `self == nil`) to prevent any such side effects.
|
|
||||||
|
|
||||||
*However*, in our experience most things that developers consider side effects that
|
|
||||||
should be protected against are in fact *not* side effects.
|
|
||||||
|
|
||||||
Side effects include changes to global application state. They *do not* include
|
|
||||||
changing the display state of a viewController. So, protect against setting UserDefaults or
|
|
||||||
modifying the application database, and don't bother protecting against changing
|
|
||||||
the text in a `UILabel`.
|
|
||||||
|
|
||||||
[This stackoverflow question](https://stackoverflow.com/questions/39281214/should-i-use-weak-self-in-promisekit-blocks)
|
|
||||||
has some good discussion on this topic.
|
|
||||||
|
|
||||||
## Do I need to retain my promises?
|
|
||||||
|
|
||||||
No. Every promise handler retains its promise until the handler is executed. Once
|
|
||||||
all handlers have been executed, the promise is deallocated. So you only need to retain
|
|
||||||
the promise if you need to refer to its final value after its chain has completed.
|
|
||||||
|
|
||||||
## Where should I put my `catch`?
|
|
||||||
|
|
||||||
`catch` deliberately terminates the chain. You should put it low in your promise
|
|
||||||
hierarchy at a point as close to the root as possible. Typically, this would be
|
|
||||||
somewhere such as a view controller, where your `catch` can then display a message
|
|
||||||
to the user.
|
|
||||||
|
|
||||||
This means you should be writing one catch for many `then`s and returning
|
|
||||||
promises that do not have internal `catch` handlers of their own.
|
|
||||||
|
|
||||||
This is obviously a guideline; do what is necessary.
|
|
||||||
|
|
||||||
## How do branched chains work?
|
|
||||||
|
|
||||||
Suppose you have a promise:
|
|
||||||
|
|
||||||
```
|
|
||||||
let promise = foo()
|
|
||||||
```
|
|
||||||
|
|
||||||
And you call `then` twice:
|
|
||||||
|
|
||||||
```
|
|
||||||
promise.then {
|
|
||||||
// branch A
|
|
||||||
}
|
|
||||||
|
|
||||||
promise.then {
|
|
||||||
// branch B
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You now have a branched chain. When `promise` resolves, both chains receive its
|
|
||||||
value. However, the two chains are entirely separate and Swift will prompt you
|
|
||||||
to ensure that both have `catch` handlers.
|
|
||||||
|
|
||||||
You can most likely ignore the `catch` for one of these branches, but be careful:
|
|
||||||
in these situations, Swift cannot help you ensure that your chains are error-handled.
|
|
||||||
|
|
||||||
```
|
|
||||||
promise.then {
|
|
||||||
// branch A
|
|
||||||
}.catch { error in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = promise.then {
|
|
||||||
print("foo")
|
|
||||||
|
|
||||||
// ignoring errors here as print cannot error and we handle errors above
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
It may be safer to recombine the two branches into a single chain again:
|
|
||||||
|
|
||||||
```
|
|
||||||
let p1 = promise.then {
|
|
||||||
// branch A
|
|
||||||
}
|
|
||||||
|
|
||||||
let p2 = promise.then {
|
|
||||||
// branch B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(fulfilled: p1, p2).catch { error in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> It's worth noting that you can add multiple `catch` handlers to a promise, too.
|
|
||||||
> And indeed, both will be called if the chain is rejected.
|
|
||||||
|
|
||||||
## Is PromiseKit “heavy”?
|
|
||||||
|
|
||||||
No. PromiseKit contains hardly any source code. In fact, it is quite lightweight. Any
|
|
||||||
“weight” relative to other promise implementations derives from 6 years of bug fixes
|
|
||||||
and tuning, from the fact that we have *stellar* Objective-C-to-Swift bridging and
|
|
||||||
from important things such as [Zalgo prevention](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
|
|
||||||
that hobby-project implementations don’t consider.
|
|
||||||
|
|
||||||
## Why is debugging hard?
|
|
||||||
|
|
||||||
Because promises always execute via dispatch, the backtrace you see at the point of
|
|
||||||
an error has less information than is usually required to trace the path of execution.
|
|
||||||
|
|
||||||
One solution is to turn off dispatch during debugging:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// Swift
|
|
||||||
DispatchQueue.default = zalgo
|
|
||||||
|
|
||||||
//ObjC
|
|
||||||
PMKSetDefaultDispatchQueue(zalgo)
|
|
||||||
```
|
|
||||||
|
|
||||||
Don’t leave this on. In normal use, we always dispatch to avoid you accidentally writing
|
|
||||||
a common bug pattern. See [this blog post](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony).
|
|
||||||
|
|
||||||
## Where is `all()`?
|
|
||||||
|
|
||||||
Some promise libraries provide `all` for awaiting multiple results. We call this function
|
|
||||||
`when`, but it is the same thing. We chose `when` because it's the more common term and
|
|
||||||
because we think it reads better in code.
|
|
||||||
|
|
||||||
## How can I test APIs that return promises?
|
|
||||||
|
|
||||||
You need to use `XCTestExpectation`.
|
|
||||||
|
|
||||||
We also define `wait()` and `hang()`. Use them if you must, but be careful because they
|
|
||||||
block the current thread!
|
|
||||||
|
|
||||||
## Is PromiseKit thread-safe?
|
|
||||||
|
|
||||||
Yes, entirely.
|
|
||||||
|
|
||||||
However the code *you* write in your `then`s might not be!
|
|
||||||
|
|
||||||
Just make sure you don’t access state outside the chain from concurrent queues.
|
|
||||||
By default, PromiseKit handlers run on the `main` thread, which is serial, so
|
|
||||||
you typically won't have to worry about this.
|
|
||||||
|
|
||||||
## Why are there separate classes for Objective-C and Swift?
|
|
||||||
|
|
||||||
`Promise<T>` is generic and and so cannot be represented by Objective-C.
|
|
||||||
|
|
||||||
## Does PromiseKit conform to Promises/A+?
|
|
||||||
|
|
||||||
Yes. We have tests that prove this.
|
|
||||||
|
|
||||||
## How do PromiseKit and RxSwift/ReactiveSwift differ?
|
|
||||||
|
|
||||||
PromiseKit is a lot simpler.
|
|
||||||
|
|
||||||
The top-level difference between PromiseKit and RxSwift is that RxSwift `Observable`s (roughly
|
|
||||||
analogous to PromiseKit `Promise`s) do not necessarily return a single result: they may emit
|
|
||||||
zero, one, or an infinite stream of values. This small conceptual change leads to an API
|
|
||||||
that's both surprisingly powerful and surprisingly complex.
|
|
||||||
|
|
||||||
RxSwift requires commitment to a paradigm shift in how you program. It proposes that you
|
|
||||||
restructure your code as a matrix of interacting value pipelines. When applied properly
|
|
||||||
to a suitable problem, RxSwift can yield great benefits in robustness and simplicity.
|
|
||||||
But not all applications are suitable for RxSwift.
|
|
||||||
|
|
||||||
By contrast, PromiseKit selectively applies the best parts of reactive programming
|
|
||||||
to the hardest part of pure Swift development, the management of asynchrony. It's a broadly
|
|
||||||
applicable tool. Most asynchronous code can be clarified, simplified and made more robust
|
|
||||||
just by converting it to use promises. (And the conversion process is easy.)
|
|
||||||
|
|
||||||
Promises make for code that is clear to most developers. RxSwift, perhaps not. Take a look at this
|
|
||||||
[signup panel](https://github.com/ReactiveX/RxSwift/tree/master/RxExample/RxExample/Examples/GitHubSignup)
|
|
||||||
implemented in RxSwift and see what you think. (Note that this is one of RxSwift's own examples.)
|
|
||||||
|
|
||||||
Even where PromiseKit and RxSwift are broadly similar, there are many differences in implementation:
|
|
||||||
|
|
||||||
* RxSwift has a separate API for chain-terminating elements ("subscribers") versus interior
|
|
||||||
elements. In PromiseKit, all elements of a chain use roughly the same code pattern.
|
|
||||||
|
|
||||||
* The RxSwift API to define an interior element of a chain (an "operator") is hair-raisingly complex.
|
|
||||||
So, RxSwift tries hard to supply every operator you might ever want to use right off the shelf. There are
|
|
||||||
hundreds. PromiseKit supplies a few utilities to help with specific scenarios, but because it's trivial
|
|
||||||
to write your own chain elements, there's no need for all this extra code in the library.
|
|
||||||
|
|
||||||
* PromiseKit dispatches the execution of every block. RxSwift dispatches only when told to do so. Moreover, the
|
|
||||||
current dispatching state is an attribute of the chain, not the specific block, as it is in PromiseKit.
|
|
||||||
The RxSwift system is more powerful but more complex. PromiseKit is simple, predictable and safe.
|
|
||||||
|
|
||||||
* In PromiseKit, both sides of a branched chain refer back to their shared common ancestors. In RxSwift,
|
|
||||||
branching normally creates a duplicate parallel chain that reruns the code at the head of the chain...except
|
|
||||||
when it doesn't. The rules for determining what will actually happen are complex, and given
|
|
||||||
a chain created by another chunk of code, you can't really tell what the behavior will be.
|
|
||||||
|
|
||||||
* Because RxSwift chains don't necessarily terminate on their own, RxSwift needs you to take on some
|
|
||||||
explicit garbage collection duties to ensure that pipelines that are no longer needed are properly
|
|
||||||
deallocated. All promises yield a single value, terminate and then automatically deallocate themselves.
|
|
||||||
|
|
||||||
You can find some additional discussion in [this ticket](https://github.com/mxcl/PromiseKit/issues/484).
|
|
||||||
|
|
||||||
## Why can’t I return from a catch like I can in Javascript?
|
|
||||||
|
|
||||||
Swift demands that functions have one purpose. Thus, we have two error handlers:
|
|
||||||
|
|
||||||
* `catch`: ends the chain and handles errors
|
|
||||||
* `recover`: attempts to recover from errors in a chain
|
|
||||||
|
|
||||||
You want `recover`.
|
|
||||||
|
|
||||||
## When do promises “start”?
|
|
||||||
|
|
||||||
Often people are confused about when Promises “start”. Is it immediately? Is it
|
|
||||||
later? Is it when you call then?
|
|
||||||
|
|
||||||
The answer is: promises do not choose when the underlying task they represent
|
|
||||||
starts. That is up to that task. For example here is the code for a simple
|
|
||||||
promise that wraps Alamofire:
|
|
||||||
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func foo() -> Promise<Any>
|
|
||||||
return Promise { seal in
|
|
||||||
Alamofire.request(rq).responseJSON { rsp in
|
|
||||||
seal.resolve(rsp.value, rsp.error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Who chooses when this promise starts? The answer is: Alamofire does, and in this
|
|
||||||
case, it “starts” immediately when `foo()` is called.
|
|
||||||
|
|
||||||
## What is a good way to use Firebase with PromiseKit
|
|
||||||
|
|
||||||
There is no good way to use Firebase with PromiseKit. See the next question for
|
|
||||||
a more detailed rationale.
|
|
||||||
|
|
||||||
The best option is to embed your chain in your Firebase handler:
|
|
||||||
|
|
||||||
```
|
|
||||||
foo.observe(.value) { snapshot in
|
|
||||||
firstly {
|
|
||||||
bar(with: snapshot)
|
|
||||||
}.then {
|
|
||||||
baz()
|
|
||||||
}.then {
|
|
||||||
baffle()
|
|
||||||
}.catch {
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## I need my `then` to fire multiple times
|
|
||||||
|
|
||||||
Then we’re afraid you cannot use PromiseKit for that event. Promises only
|
|
||||||
resolve *once*. This is the fundamental nature of promises and it is considered a
|
|
||||||
feature because it gives you guarantees about the flow of your chains.
|
|
||||||
|
|
||||||
|
|
||||||
## How do I change the default queues that handlers run on?
|
|
||||||
|
|
||||||
You can change the values of `PromiseKit.conf.Q`. There are two variables that
|
|
||||||
change the default queues that the two kinds of handler run on. A typical
|
|
||||||
pattern is to change all your `then`-type handlers to run on a background queue
|
|
||||||
and to have all your “finalizers” run on the main queue:
|
|
||||||
|
|
||||||
```
|
|
||||||
PromiseKit.conf.Q.map = .global()
|
|
||||||
PromiseKit.conf.Q.return = .main //NOTE this is the default
|
|
||||||
```
|
|
||||||
|
|
||||||
Be very careful about setting either of these queues to `nil`. It has the
|
|
||||||
effect of running *immediately*, and this is not what you usually want to do in
|
|
||||||
your application. This is, however, useful when you are running specs and want
|
|
||||||
your promises to resolve immediately. (This is basically the same idea as "stubbing"
|
|
||||||
an HTTP request.)
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// in your test suite setup code
|
|
||||||
PromiseKit.conf.Q.map = nil
|
|
||||||
PromiseKit.conf.Q.return = nil
|
|
||||||
```
|
|
||||||
|
|
||||||
## How do I use PromiseKit on the server side?
|
|
||||||
|
|
||||||
If your server framework requires that the main queue remain unused (e.g., Kitura),
|
|
||||||
then you must use PromiseKit 6 and you must tell PromiseKit not to dispatch to the
|
|
||||||
main queue by default. This is easy enough:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
PromiseKit.conf.Q = (map: DispatchQueue.global(), return: DispatchQueue.global())
|
|
||||||
```
|
|
||||||
|
|
||||||
> Note, we recommend using your own queue rather than `.global()`, we've seen better performance this way.
|
|
||||||
|
|
||||||
Here’s a more complete example:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
import Foundation
|
|
||||||
import HeliumLogger
|
|
||||||
import Kitura
|
|
||||||
import LoggerAPI
|
|
||||||
import PromiseKit
|
|
||||||
|
|
||||||
HeliumLogger.use(.info)
|
|
||||||
|
|
||||||
let pmkQ = DispatchQueue(label: "pmkQ", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem)
|
|
||||||
PromiseKit.conf.Q = (map: pmkQ, return: pmkQ)
|
|
||||||
|
|
||||||
let router = Router()
|
|
||||||
router.get("/") { _, response, next in
|
|
||||||
Log.info("Request received")
|
|
||||||
after(seconds: 1.0).done {
|
|
||||||
Log.info("Sending response")
|
|
||||||
response.send("OK")
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.info("Starting server")
|
|
||||||
Kitura.addHTTPServer(onPort: 8888, with: router)
|
|
||||||
Kitura.run()
|
|
||||||
```
|
|
||||||
|
|
||||||
## My question was not answered
|
|
||||||
|
|
||||||
[Please open a ticket](https://github.com/mxcl/PromiseKit/issues/new).
|
|
@@ -1,535 +0,0 @@
|
|||||||
# `then` and `done`
|
|
||||||
|
|
||||||
Here is a typical promise chain:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
login()
|
|
||||||
}.then { creds in
|
|
||||||
fetch(avatar: creds.user)
|
|
||||||
}.done { image in
|
|
||||||
self.imageView = image
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If this code used completion handlers, it would look like this:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
login { creds, error in
|
|
||||||
if let creds = creds {
|
|
||||||
fetch(avatar: creds.user) { image, error in
|
|
||||||
if let image = image {
|
|
||||||
self.imageView = image
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`then` *is* just another way to structure completion handlers, but it is also quite a
|
|
||||||
bit more. At this initial stage of our understanding, it mostly helps
|
|
||||||
readability. The promise chain above is easy to scan and understand: one asynchronous
|
|
||||||
operation leads into the other, line by line. It's as close to
|
|
||||||
procedural code as we can easily come given the current state of Swift.
|
|
||||||
|
|
||||||
`done` is the same as `then` but you cannot return a promise. It is
|
|
||||||
typically the end of the “success” part of the chain. Above, you can see that we
|
|
||||||
receive the final image in our `done` and use it to set up the UI.
|
|
||||||
|
|
||||||
Let’s compare the signatures of the two login methods:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func login() -> Promise<Creds>
|
|
||||||
|
|
||||||
// Compared with:
|
|
||||||
|
|
||||||
func login(completion: (Creds?, Error?) -> Void)
|
|
||||||
// ^^ ugh. Optionals. Double optionals.
|
|
||||||
```
|
|
||||||
|
|
||||||
The distinction is that with promises, your functions return *promises* instead
|
|
||||||
of accepting and running callbacks. Each handler in a chain returns a promise.
|
|
||||||
`Promise` objects define the `then` method, which waits for the completion of the
|
|
||||||
promise before continuing the chain. Chains resolve procedurally, one promise
|
|
||||||
at a time.
|
|
||||||
|
|
||||||
A `Promise` represents the future value of an asynchronous task. It has a type
|
|
||||||
that represents the type of object it wraps. For example, in the example above,
|
|
||||||
`login` is a function that returns a `Promise` that *will* represent an instance
|
|
||||||
of `Creds`.
|
|
||||||
|
|
||||||
> *Note*: `done` is new to PromiseKit 5. We previously defined a variant of `then` that
|
|
||||||
did not require you to return a promise. Unfortunately, this convention often confused
|
|
||||||
Swift and led to odd and hard-to-debug error messages. It also made using PromiseKit
|
|
||||||
more painful. The introduction of `done` lets you type out promise chains that
|
|
||||||
compile without additional qualification to help the compiler figure out type information.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
You may notice that unlike the completion pattern, the promise chain appears to
|
|
||||||
ignore errors. This is not the case! In fact, it has the opposite effect: the promise
|
|
||||||
chain makes error handling more accessible and makes errors harder to ignore.
|
|
||||||
|
|
||||||
|
|
||||||
# `catch`
|
|
||||||
|
|
||||||
With promises, errors cascade along the promise chain, ensuring that your apps are
|
|
||||||
robust and your code is clear:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
login()
|
|
||||||
}.then { creds in
|
|
||||||
fetch(avatar: creds.user)
|
|
||||||
}.done { image in
|
|
||||||
self.imageView = image
|
|
||||||
}.catch {
|
|
||||||
// any errors in the whole chain land here
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> Swift emits a warning if you forget to `catch` a chain. But we'll
|
|
||||||
> talk about that in more detail later.
|
|
||||||
|
|
||||||
Each promise is an object that represents an individual, asychnronous task.
|
|
||||||
If a task fails, its promise becomes *rejected*. Chains that contain rejected
|
|
||||||
promises skip all subsequent `then`s. Instead, the next `catch` is executed.
|
|
||||||
(Strictly speaking, *all* subsequent `catch` handlers are executed.)
|
|
||||||
|
|
||||||
For fun, let’s compare this pattern with its completion handler equivalent:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func handle(error: Error) {
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
|
|
||||||
login { creds, error in
|
|
||||||
guard let creds = creds else { return handle(error: error!) }
|
|
||||||
fetch(avatar: creds.user) { image, error in
|
|
||||||
guard let image = image else { return handle(error: error!) }
|
|
||||||
self.imageView.image = image
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The use of `guard` and a consolidated error handler help, but the promise chain’s
|
|
||||||
readability speaks for itself.
|
|
||||||
|
|
||||||
|
|
||||||
# `ensure`
|
|
||||||
|
|
||||||
We have learned to compose asynchronicity. Next let’s extend our primitives:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
UIApplication.shared.isNetworkActivityIndicatorVisible = true
|
|
||||||
return login()
|
|
||||||
}.then {
|
|
||||||
fetch(avatar: $0.user)
|
|
||||||
}.done {
|
|
||||||
self.imageView = $0
|
|
||||||
}.ensure {
|
|
||||||
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
|
||||||
}.catch {
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
No matter the outcome of your chain—-failure or success—-your `ensure`
|
|
||||||
handler is always called.
|
|
||||||
|
|
||||||
Let’s compare this pattern with its completion handler equivalent:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
UIApplication.shared.isNetworkActivityIndicatorVisible = true
|
|
||||||
|
|
||||||
func handle(error: Error) {
|
|
||||||
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
|
|
||||||
login { creds, error in
|
|
||||||
guard let creds = creds else { return handle(error: error!) }
|
|
||||||
fetch(avatar: creds.user) { image, error in
|
|
||||||
guard let image = image else { return handle(error: error!) }
|
|
||||||
self.imageView.image = image
|
|
||||||
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
It would be very easy for someone to amend this code and forget to unset
|
|
||||||
the activity indicator, leading to a bug. With promises, this type of error is
|
|
||||||
almost impossible: the Swift compiler resists your supplementing the chain without
|
|
||||||
using promises. You almost won’t need to review the pull requests.
|
|
||||||
|
|
||||||
> *Note*: PromiseKit has perhaps capriciously switched between the names `always`
|
|
||||||
and `ensure` for this function several times in the past. Sorry about this. We suck.
|
|
||||||
|
|
||||||
You can also use `finally` as an `ensure` that terminates the promise chain and does not return a value:
|
|
||||||
|
|
||||||
```
|
|
||||||
spinner(visible: true)
|
|
||||||
|
|
||||||
firstly {
|
|
||||||
foo()
|
|
||||||
}.done {
|
|
||||||
//…
|
|
||||||
}.catch {
|
|
||||||
//…
|
|
||||||
}.finally {
|
|
||||||
self.spinner(visible: false)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
# `when`
|
|
||||||
|
|
||||||
With completion handlers, reacting to multiple asynchronous operations is either
|
|
||||||
slow or hard. Slow means doing it serially:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
operation1 { result1 in
|
|
||||||
operation2 { result2 in
|
|
||||||
finish(result1, result2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The fast (*parallel*) path code makes the code less clear:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
var result1: …!
|
|
||||||
var result2: …!
|
|
||||||
let group = DispatchGroup()
|
|
||||||
group.enter()
|
|
||||||
group.enter()
|
|
||||||
operation1 {
|
|
||||||
result1 = $0
|
|
||||||
group.leave()
|
|
||||||
}
|
|
||||||
operation2 {
|
|
||||||
result2 = $0
|
|
||||||
group.leave()
|
|
||||||
}
|
|
||||||
group.notify(queue: .main) {
|
|
||||||
finish(result1, result2)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Promises are easier:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
when(fulfilled: operation1(), operation2())
|
|
||||||
}.done { result1, result2 in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`when` takes promises, waits for them to resolve and returns a promise containing the results.
|
|
||||||
|
|
||||||
As with any promise chain, if any of the component promises fail, the chain calls the next `catch`.
|
|
||||||
|
|
||||||
|
|
||||||
# PromiseKit Extensions
|
|
||||||
|
|
||||||
When we made PromiseKit, we understood that we wanted to use *only* promises to implement
|
|
||||||
asynchronous behavior. So wherever possible, we offer extensions to Apple’s APIs that reframe
|
|
||||||
the API in terms of promises. For example:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
CLLocationManager.promise()
|
|
||||||
}.then { location in
|
|
||||||
CLGeocoder.reverseGeocode(location)
|
|
||||||
}.done { placemarks in
|
|
||||||
self.placemark.text = "\(placemarks.first)"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
To use these extensions, you need to specify subspecs:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
pod "PromiseKit"
|
|
||||||
pod "PromiseKit/CoreLocation"
|
|
||||||
pod "PromiseKit/MapKit"
|
|
||||||
```
|
|
||||||
|
|
||||||
All of these extensions are available at the [PromiseKit organization](https://github.com/PromiseKit).
|
|
||||||
Go there to see what's available and to read the source code and documentation. Every file and function
|
|
||||||
has been copiously documented.
|
|
||||||
|
|
||||||
> We also provide extensions for common libraries such as [Alamofire](https://github.com/PromiseKit/Alamofire-).
|
|
||||||
|
|
||||||
|
|
||||||
# Making Promises
|
|
||||||
|
|
||||||
The standard extensions will take you a long way, but sometimes you'll still need to start chains
|
|
||||||
of your own. Maybe you're using a third party API that doesn’t provide promises, or perhaps you wrote
|
|
||||||
your own asynchronous system. Either way, it's easy to add promises. If you look at the code of the
|
|
||||||
standard extensions, you'll see that it uses the same approach described below.
|
|
||||||
|
|
||||||
Let’s say we have the following method:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func fetch(completion: (String?, Error?) -> Void)
|
|
||||||
```
|
|
||||||
|
|
||||||
How do we convert this to a promise? Well, it's easy:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func fetch() -> Promise<String> {
|
|
||||||
return Promise { fetch(completion: $0.resolve) }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You may find the expanded version more readable:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func fetch() -> Promise<String> {
|
|
||||||
return Promise { seal in
|
|
||||||
fetch { result, error in
|
|
||||||
seal.resolve(result, error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `seal` object that the `Promise` initializer provides to you defines
|
|
||||||
many methods for handling garden-variety completion handlers. It even
|
|
||||||
covers a variety of rarer situations, thus making it easy for you to add
|
|
||||||
promises to an existing codebase.
|
|
||||||
|
|
||||||
> *Note*: We tried to make it so that you could just do `Promise(fetch)`, but we
|
|
||||||
were not able to make this simpler pattern work universally without requiring
|
|
||||||
extra disambiguation for the Swift compiler. Sorry; we tried.
|
|
||||||
|
|
||||||
> *Note*: In PMK 4, this initializer provided two parameters to your closure:
|
|
||||||
`fulfill` and `reject`. PMK 5 and 6 give you an object that has both `fulfill` and
|
|
||||||
`reject` methods, but also many variants of the method `resolve`. You can
|
|
||||||
typically just pass completion handler parameters to `resolve` and let Swift figure
|
|
||||||
out which variant to apply to your particular case (as shown in the example above).
|
|
||||||
|
|
||||||
> *Note* `Guarantees` (below) have a slightly different initializer (since they
|
|
||||||
cannot error) so the parameter to the initializer closure is just a closure. Not
|
|
||||||
a `Resolver` object. Thus do `seal(value)` rather than `seal.fulfill(value)`. This
|
|
||||||
is because there is no variations in what guarantees can be sealed with, they can
|
|
||||||
*only* fulfill.
|
|
||||||
|
|
||||||
# `Guarantee<T>`
|
|
||||||
|
|
||||||
Since PromiseKit 5, we have provided `Guarantee` as a supplementary class to
|
|
||||||
`Promise`. We do this to complement Swift’s strong error handling system.
|
|
||||||
|
|
||||||
Guarantees *never* fail, so they cannot be rejected. A good example is `after`:
|
|
||||||
|
|
||||||
```
|
|
||||||
firstly {
|
|
||||||
after(seconds: 0.1)
|
|
||||||
}.done {
|
|
||||||
// there is no way to add a `catch` because after cannot fail.
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Swift warns you if you don’t terminate a regular `Promise` chain (i.e., not
|
|
||||||
a `Guarantee` chain). You're expected to silence this warning by supplying
|
|
||||||
either a `catch` or a `return`. (In the latter case, you will then have to `catch`
|
|
||||||
at the point where you receive that promise.)
|
|
||||||
|
|
||||||
Use `Guarantee`s wherever possible so that your code has error handling where
|
|
||||||
it's required and no error handling where it's not required.
|
|
||||||
|
|
||||||
In general, you should be able to use `Guarantee`s and `Promise`s interchangeably,
|
|
||||||
We have gone to great lengths to try and ensure this, so please open a ticket
|
|
||||||
if you find an issue.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
If you are creating your own guarantees the syntax is simpler than that of promises;
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func fetch() -> Promise<String> {
|
|
||||||
return Guarantee { seal in
|
|
||||||
fetch { result in
|
|
||||||
seal(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Which could be reduced to:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func fetch() -> Promise<String> {
|
|
||||||
return Guarantee(resolver: fetch)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# `map`, `compactMap`, etc.
|
|
||||||
|
|
||||||
`then` provides you with the result of the previous promise and requires you to return
|
|
||||||
another promise.
|
|
||||||
|
|
||||||
`map` provides you with the result of the previous promise and requires you to return
|
|
||||||
an object or value type.
|
|
||||||
|
|
||||||
`compactMap` provides you with the result of the previous promise and requires you
|
|
||||||
to return an `Optional`. If you return `nil`, the chain fails with
|
|
||||||
`PMKError.compactMap`.
|
|
||||||
|
|
||||||
> *Rationale*: Before PromiseKit 4, `then` handled all these cases, and it was
|
|
||||||
painful. We hoped the pain would disappear with new Swift versions. However,
|
|
||||||
it has become clear that the various pain points are here to stay. In fact, we
|
|
||||||
as library authors are expected to disambiguate at the naming level of our API.
|
|
||||||
Therefore, we have split the three main kinds of `then` into `then`, `map` and
|
|
||||||
`done`. After using these new functions, we realized this is much nicer in practice,
|
|
||||||
so we added `compactMap` as well (modeled on `Optional.compactMap`).
|
|
||||||
|
|
||||||
`compactMap` facilitates quick composition of promise chains. For example:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
URLSession.shared.dataTask(.promise, with: rq)
|
|
||||||
}.compactMap {
|
|
||||||
try JSONSerialization.jsonObject($0.data) as? [String]
|
|
||||||
}.done { arrayOfStrings in
|
|
||||||
//…
|
|
||||||
}.catch { error in
|
|
||||||
// Foundation.JSONError if JSON was badly formed
|
|
||||||
// PMKError.compactMap if JSON was of different type
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> *Tip*: We also provide most of the functional methods you would expect for sequences,
|
|
||||||
e.g., `map`, `thenMap`, `compactMapValues`, `firstValue`, etc.
|
|
||||||
|
|
||||||
|
|
||||||
# `get`
|
|
||||||
|
|
||||||
We provide `get` as a `done` that returns the value fed to `get`.
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
foo()
|
|
||||||
}.get { foo in
|
|
||||||
//…
|
|
||||||
}.done { foo in
|
|
||||||
// same foo!
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
# `tap`
|
|
||||||
|
|
||||||
We provide `tap` for debugging. It's the same as `get` but provides the
|
|
||||||
`Result<T>` of the `Promise` so you can inspect the value of the chain at this
|
|
||||||
point without causing any side effects:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
foo()
|
|
||||||
}.tap {
|
|
||||||
print($0)
|
|
||||||
}.done {
|
|
||||||
//…
|
|
||||||
}.catch {
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
# Supplement
|
|
||||||
|
|
||||||
## `firstly`
|
|
||||||
|
|
||||||
We've used `firstly` several times on this page, but what is it, really? In fact,
|
|
||||||
it is just [syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar).
|
|
||||||
You don’t really need it, but it helps to make your chains more readable. Instead of:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
firstly {
|
|
||||||
login()
|
|
||||||
}.then { creds in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You could just do:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
login().then { creds in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Here is a key understanding: `login()` returns a `Promise`, and all `Promise`s have a `then` function. `firstly` returns a `Promise`, and `then` returns a `Promise`, too! But don’t worry too much about these details. Learn the *patterns* to start with. Then, when you are ready to advance, learn the underlying architecture.
|
|
||||||
|
|
||||||
|
|
||||||
## `when` Variants
|
|
||||||
|
|
||||||
`when` is one of PromiseKit’s more useful functions, and so we offer several variants.
|
|
||||||
|
|
||||||
* The default `when`, and the one you should typically use, is `when(fulfilled:)`. This variant
|
|
||||||
waits on all its component promises, but if any fail, `when` fails too, and thus the chain *rejects*.
|
|
||||||
It's important to note that all promises in the `when` *continue*. Promises have *no* control over
|
|
||||||
the tasks they represent. Promises are just wrappers around tasks.
|
|
||||||
|
|
||||||
* `when(resolved:)` waits even if one or more of its component promises fails. The value produced
|
|
||||||
by this variant of `when` is an array of `Result<T>`. Consequently, this variant requires all its
|
|
||||||
component promises to have the same generic type. See our advanced patterns guide for work-arounds
|
|
||||||
for this limitation.
|
|
||||||
|
|
||||||
* The `race` variant lets you *race* several promises. Whichever finishes first is the result. See the
|
|
||||||
advanced patterns guide for typical usage.
|
|
||||||
|
|
||||||
|
|
||||||
## Swift Closure Inference
|
|
||||||
|
|
||||||
Swift automatically infers returns and return types for one-line closures.
|
|
||||||
The following two forms are the same:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
foo.then {
|
|
||||||
bar($0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// is the same as:
|
|
||||||
|
|
||||||
foo.then { baz -> Promise<String> in
|
|
||||||
return bar(baz)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Our documentation often omits the `return` for clarity.
|
|
||||||
|
|
||||||
However, this shorthand is both a blessing and a curse. You may find that the Swift compiler
|
|
||||||
often fails to infer return types properly. See our [Troubleshooting Guide](Troubleshooting.md) if
|
|
||||||
you require further assistance.
|
|
||||||
|
|
||||||
> By adding `done` to PromiseKit 5, we have managed to avoid many of these common
|
|
||||||
pain points in using PromiseKit and Swift.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Further Reading
|
|
||||||
|
|
||||||
The above information is the 90% you will use. We **strongly** suggest reading the
|
|
||||||
[API Reference].
|
|
||||||
There are numerous little
|
|
||||||
functions that may be useful to you, and the documentation for everything outlined above
|
|
||||||
is more thorough at the source.
|
|
||||||
|
|
||||||
In Xcode, don’t forget to option-click on PromiseKit functions to access this
|
|
||||||
documentation while you're coding.
|
|
||||||
|
|
||||||
Here are some recent articles that document PromiseKit 5+:
|
|
||||||
|
|
||||||
* [Using Promises - Agostini.tech](https://agostini.tech/2018/10/08/using-promisekit)
|
|
||||||
|
|
||||||
Careful with general online references, many of them refer to PMK < 5 which has a subtly
|
|
||||||
different API (sorry about that, but Swift has changed a lot over the years and thus
|
|
||||||
we had to too).
|
|
||||||
|
|
||||||
|
|
||||||
[API Reference]: https://promisekit.org/reference/
|
|
@@ -1,193 +0,0 @@
|
|||||||
# Xcode 8.3, 9.x or 10.x / Swift 3 or 4
|
|
||||||
|
|
||||||
We recommend Carthage over CocoaPods, but both installation methods are supported.
|
|
||||||
|
|
||||||
## CocoaPods
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
use_frameworks!
|
|
||||||
|
|
||||||
target "Change Me!" do
|
|
||||||
pod "PromiseKit", "~> 6.0"
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
If the generated Xcode project gives you a warning that PromiseKit needs to be upgraded to
|
|
||||||
Swift 4.0 or Swift 4.2, then add the following:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
post_install do |installer|
|
|
||||||
installer.pods_project.targets.each do |target|
|
|
||||||
if target.name == 'PromiseKit'
|
|
||||||
target.build_configurations.each do |config|
|
|
||||||
config.build_settings['SWIFT_VERSION'] = '4.2'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
Adjust the value for `SWIFT_VERSION` as needed.
|
|
||||||
|
|
||||||
CocoaPods are aware of this [issue](https://github.com/CocoaPods/CocoaPods/issues/7134).
|
|
||||||
|
|
||||||
## Carthage
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
github "mxcl/PromiseKit" ~> 6.0
|
|
||||||
```
|
|
||||||
|
|
||||||
## SwiftPM
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
package.dependencies.append(
|
|
||||||
.Package(url: "https://github.com/mxcl/PromiseKit", majorVersion: 6)
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Manually
|
|
||||||
|
|
||||||
You can just drop `PromiseKit.xcodeproj` into your project and then add
|
|
||||||
`PromiseKit.framework` to your app’s embedded frameworks.
|
|
||||||
|
|
||||||
|
|
||||||
# PromiseKit vs. Xcode
|
|
||||||
|
|
||||||
PromiseKit contains Swift, so there have been rev-lock issues with Xcode:
|
|
||||||
|
|
||||||
| PromiseKit | Swift | Xcode | CI Status | Release Notes |
|
|
||||||
| ---------- | ----------------------- | -------- | ------------ | ----------------- |
|
|
||||||
| 6 | 3.1, 3.2, 3.3, 4.x | 8.3, 9.x, 10.x | ![ci-master] | [2018/02][news-6] |
|
|
||||||
| 5 | 3.1, 3.2, 3.3, 4.x | 8.3, 9.x | *Deprecated* | *n/a* |
|
|
||||||
| 4† | 3.0, 3.1, 3.2, 3.3, 4.x | 8.x, 9.x | ![ci-master] | [2016/09][news-4] |
|
|
||||||
| 3 | 2.x | 7.x, 8.0 | ![ci-swift2] | [2015/10][news-3] |
|
|
||||||
| 2 | 1.x | 7.x | *Deprecated* | [2015/10][news-3] |
|
|
||||||
| 1‡ | *N/A* | * | ![ci-legacy] | – |
|
|
||||||
|
|
||||||
† Probably supports Xcode 10 and Swift 4.2, if not, PR welcome.
|
|
||||||
|
|
||||||
‡ PromiseKit 1 is pure Objective-C and thus can be used with any Xcode, it is
|
|
||||||
also your only choice if you need to support iOS 7 or below.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
We also maintain a series of branches to aid migration for PromiseKit 2:
|
|
||||||
|
|
||||||
| Xcode | Swift | PromiseKit | Branch | CI Status |
|
|
||||||
| ----- | ----- | -----------| --------------------------- | --------- |
|
|
||||||
| 8.0 | 2.3 | 2 | [swift-2.3-minimal-changes] | ![ci-23] |
|
|
||||||
| 7.3 | 2.2 | 2 | [swift-2.2-minimal-changes] | ![ci-22] |
|
|
||||||
| 7.2 | 2.2 | 2 | [swift-2.2-minimal-changes] | ![ci-22] |
|
|
||||||
| 7.1 | 2.1 | 2 | [swift-2.0-minimal-changes] | ![ci-20] |
|
|
||||||
| 7.0 | 2.0 | 2 | [swift-2.0-minimal-changes] | ![ci-20] |
|
|
||||||
|
|
||||||
We do **not** usually backport fixes to these branches, but pull requests are welcome.
|
|
||||||
|
|
||||||
|
|
||||||
## Xcode 8 / Swift 2.3 or Xcode 7
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# CocoaPods
|
|
||||||
swift_version = "2.3"
|
|
||||||
pod "PromiseKit", "~> 3.5"
|
|
||||||
|
|
||||||
# Carthage
|
|
||||||
github "mxcl/PromiseKit" ~> 3.5
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
[travis]: https://travis-ci.org/mxcl/PromiseKit
|
|
||||||
[ci-master]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=master
|
|
||||||
[ci-legacy]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=legacy-1.x
|
|
||||||
[ci-swift2]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.x
|
|
||||||
[ci-23]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.3-minimal-changes
|
|
||||||
[ci-22]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.2-minimal-changes
|
|
||||||
[ci-20]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.0-minimal-changes
|
|
||||||
[news-2]: http://promisekit.org/news/2015/05/PromiseKit-2.0-Released/
|
|
||||||
[news-3]: https://github.com/mxcl/PromiseKit/blob/master/CHANGELOG.markdown#300-oct-1st-2015
|
|
||||||
[news-4]: http://promisekit.org/news/2016/09/PromiseKit-4.0-Released/
|
|
||||||
[news-6]: http://promisekit.org/news/2018/02/PromiseKit-6.0-Released/
|
|
||||||
[swift-2.3-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.3-minimal-changes
|
|
||||||
[swift-2.2-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.2-minimal-changes
|
|
||||||
[swift-2.0-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.0-minimal-changes
|
|
||||||
|
|
||||||
|
|
||||||
# Using Git Submodules for PromiseKit’s Extensions
|
|
||||||
|
|
||||||
> *Note*: This is a more advanced technique.
|
|
||||||
|
|
||||||
If you use CocoaPods and a few PromiseKit extensions, then importing PromiseKit
|
|
||||||
causes that module to import all the extension frameworks. Thus, if you have an
|
|
||||||
app and a few app extensions (e.g., iOS app, iOS watch extension, iOS Today
|
|
||||||
extension) then all your final products that use PromiseKit will have forced
|
|
||||||
dependencies on all the Apple frameworks that PromiseKit provides extensions
|
|
||||||
for.
|
|
||||||
|
|
||||||
This isn’t that bad, but every framework that loads entails overhead and
|
|
||||||
lengthens startup time.
|
|
||||||
|
|
||||||
It’s both better and worse with Carthage. We build individual micro-frameworks
|
|
||||||
for each PromiseKit extension, so your final products link
|
|
||||||
against only the Apple frameworks that they actually need. However, Apple has
|
|
||||||
advised that apps link only against “about 12” frameworks for performance
|
|
||||||
reasons. So with Carthage, we are worse off on this metric.
|
|
||||||
|
|
||||||
The solution is to instead import only CorePromise:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# CocoaPods
|
|
||||||
pod "PromiseKit/CorePromise"
|
|
||||||
|
|
||||||
# Carthage
|
|
||||||
github "mxcl/PromiseKit"
|
|
||||||
# ^^ for Carthage *only* have this
|
|
||||||
```
|
|
||||||
|
|
||||||
And to use the extensions you need via `git submodules`:
|
|
||||||
|
|
||||||
```
|
|
||||||
git submodule init
|
|
||||||
git submodule add https://github.com/PromiseKit/UIKit Submodules/PMKUIKit
|
|
||||||
```
|
|
||||||
|
|
||||||
Then in Xcode you can add these sources to your targets on a per-target basis.
|
|
||||||
|
|
||||||
Then when you `pod update`, ensure that you also update your submodules:
|
|
||||||
|
|
||||||
pod update && git submodule update --recursive --remote
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Release History
|
|
||||||
|
|
||||||
## [6.0](https://github.com/mxcl/PromiseKit/releases/tag/6.0.0) Feb 13th, 2018
|
|
||||||
|
|
||||||
* [PromiseKit 6 announcement post][news-6].
|
|
||||||
|
|
||||||
## [4.0](https://github.com/mxcl/PromiseKit/releases/tag/4.0.0)
|
|
||||||
|
|
||||||
* [PromiseKit 4 announcement post][news-4].
|
|
||||||
|
|
||||||
## [3.0](https://github.com/mxcl/PromiseKit/releases/tag/3.0.0) Oct 1st, 2015
|
|
||||||
|
|
||||||
In Swift 2.0 `catch` and `defer` became reserved keywords mandating we rename
|
|
||||||
our functions with these names. This forced a major semantic version change on
|
|
||||||
PromiseKit and thus we took the opportunity to make other minor (source
|
|
||||||
compatibility breaking) improvements.
|
|
||||||
|
|
||||||
Thus if you cannot afford to adapt to PromiseKit 3 but still want to use
|
|
||||||
Xcode-7.0/Swift-2.0 we provide a [minimal changes branch] where `catch` and
|
|
||||||
`defer` are renamed `catch_` and `defer_` and all other changes are the bare
|
|
||||||
minimum to make PromiseKit 2 compile against Swift 2.
|
|
||||||
|
|
||||||
If you still are using Xcode 6 and Swift 1.2 then use PromiseKit 2.
|
|
||||||
|
|
||||||
[minimal changes branch]: https://github.com/mxcl/PromiseKit/tree/swift-2.0-minimal-changes
|
|
||||||
|
|
||||||
## [2.0](https://github.com/mxcl/PromiseKit/releases/tag/2.0.0) May 14th, 2015
|
|
||||||
|
|
||||||
[PromiseKit 2 announcement post](http://promisekit.org/news/2015/05/PromiseKit-2.0-Released/).
|
|
||||||
|
|
||||||
## [1.5](https://github.com/mxcl/PromiseKit/releases/tag/1.5.0)
|
|
||||||
|
|
||||||
Swift 1.2 support. Xcode 6.3 required.
|
|
@@ -1,201 +0,0 @@
|
|||||||
# Objective-C
|
|
||||||
|
|
||||||
PromiseKit has two promise classes:
|
|
||||||
|
|
||||||
* `Promise<T>` (Swift)
|
|
||||||
* `AnyPromise` (Objective-C)
|
|
||||||
|
|
||||||
Each is designed to be an appropriate promise implementation for the strong points of its language:
|
|
||||||
|
|
||||||
* `Promise<T>` is strict, defined and precise.
|
|
||||||
* `AnyPromise` is loose and dynamic.
|
|
||||||
|
|
||||||
Unlike most libraries, we have extensive bridging support, you can use PromiseKit
|
|
||||||
in mixed projects with mixed language targets and mixed language libraries.
|
|
||||||
|
|
||||||
|
|
||||||
# Using PromiseKit with Objective-C
|
|
||||||
|
|
||||||
`AnyPromise` is our promise class for Objective-C. It behaves almost identically to `Promise<T>`, our Swift promise class.
|
|
||||||
|
|
||||||
```objc
|
|
||||||
myPromise.then(^(NSString *bar){
|
|
||||||
return anotherPromise;
|
|
||||||
}).then(^{
|
|
||||||
//…
|
|
||||||
}).catch(^(NSError *error){
|
|
||||||
//…
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
You make new promises using `promiseWithResolverBlock`:
|
|
||||||
|
|
||||||
```objc
|
|
||||||
- (AnyPromise *)myPromise {
|
|
||||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve){
|
|
||||||
resolve(foo); // if foo is an NSError, rejects, else, resolves
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
You reject promises by throwing errors:
|
|
||||||
|
|
||||||
```objc
|
|
||||||
myPromise.then(^{
|
|
||||||
@throw [NSError errorWithDomain:domain code:code userInfo:nil];
|
|
||||||
}).catch(^(NSError *error){
|
|
||||||
//…
|
|
||||||
});
|
|
||||||
```
|
|
||||||
#### :warning: Caution:
|
|
||||||
ARC in Objective-C, unlike in Objective-C++, is not exception-safe by default.
|
|
||||||
So, throwing an error will result in keeping a strong reference to the closure
|
|
||||||
that contains the throw statement.
|
|
||||||
This pattern will consequently result in memory leaks if you're not careful.
|
|
||||||
|
|
||||||
> *Note:* Only having a strong reference to the closure would result in memory leaks.
|
|
||||||
> In our case, PromisKit automatically keeps a strong reference to the closure until it's released.
|
|
||||||
|
|
||||||
__Workarounds:__
|
|
||||||
1. Return a Promise with value NSError\
|
|
||||||
Instead of throwing a normal error, you can return a Promise with value NSError instead.
|
|
||||||
|
|
||||||
```objc
|
|
||||||
myPromise.then(^{
|
|
||||||
return [AnyPromise promiseWithValue:[NSError myCustomError]];
|
|
||||||
}).catch(^(NSError *error){
|
|
||||||
if ([error isEqual:[NSError myCustomError]]) {
|
|
||||||
// In case, same error as the one we thrown
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//…
|
|
||||||
});
|
|
||||||
```
|
|
||||||
2. Enable ARC for exceptions in Objective-C (not recomended)\
|
|
||||||
You can add this ```-fobjc-arc-exceptions to your``` to your compiler flags to enable ARC for exceptions.
|
|
||||||
This is not recommended unless you've read the Apple documentation and are comfortable with the caveats.
|
|
||||||
|
|
||||||
For more details on ARC and exceptions:
|
|
||||||
https://clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
One important feature is the syntactic flexability of your handlers:
|
|
||||||
|
|
||||||
```objc
|
|
||||||
myPromise.then(^{
|
|
||||||
// no parameters is fine
|
|
||||||
});
|
|
||||||
|
|
||||||
myPromise.then(^(id foo){
|
|
||||||
// one parameter is fine
|
|
||||||
});
|
|
||||||
|
|
||||||
myPromise.then(^(id a, id b, id c){
|
|
||||||
// up to three parameter is fine, no crash!
|
|
||||||
});
|
|
||||||
|
|
||||||
myPromise.then(^{
|
|
||||||
return @1; // return anything or nothing, it's fine, no crash
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
We do runtime inspection of the block you pass to achieve this magic.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Another important distinction is that the equivalent function to Swift’s `recover` is combined with `AnyPromise`’s `catch`. This is typical to other “dynamic” promise implementations and thus achieves our goal that `AnyPromise` is loose and dynamic while `Promise<T>` is strict and specific.
|
|
||||||
|
|
||||||
A sometimes unexpected consequence of this fact is that returning nothing from a `catch` *resolves* the returned promise:
|
|
||||||
|
|
||||||
```objc
|
|
||||||
myPromise.catch(^{
|
|
||||||
[UIAlertView …];
|
|
||||||
}).then(^{
|
|
||||||
// always executes!
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Another important distinction is that the `value` property returns even if the promise is rejected; in that case, it returns the `NSError` object with which the promise was rejected.
|
|
||||||
|
|
||||||
|
|
||||||
# Bridging Between Objective-C & Swift
|
|
||||||
|
|
||||||
Let’s say you have:
|
|
||||||
|
|
||||||
```objc
|
|
||||||
@interface Foo
|
|
||||||
- (AnyPromise *)myPromise;
|
|
||||||
@end
|
|
||||||
```
|
|
||||||
|
|
||||||
Ensure that this interface is included in your bridging header. You can now use the
|
|
||||||
following pattern in your Swift code:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
let foo = Foo()
|
|
||||||
foo.myPromise.then { (obj: AnyObject?) -> Int in
|
|
||||||
// it is not necessary to specify the type of `obj`
|
|
||||||
// we just do that for demonstrative purposes
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Let’s say you have:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
@objc class Foo: NSObject {
|
|
||||||
func stringPromise() -> Promise<String>
|
|
||||||
func barPromise() -> Promise<Bar>
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc class Bar: NSObject { /*…*/ }
|
|
||||||
```
|
|
||||||
|
|
||||||
Ensure that your project is generating a `…-Swift.h` header so that Objective-C can see your Swift code.
|
|
||||||
|
|
||||||
If you built this project and opened the `…-Swift.h` header, you would only see this:
|
|
||||||
|
|
||||||
```objc
|
|
||||||
@interface Foo
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface Bar
|
|
||||||
@end
|
|
||||||
```
|
|
||||||
|
|
||||||
That's because Objective-C cannot import Swift objects that are generic. So we need to write some stubs:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
@objc class Foo: NSObject {
|
|
||||||
@objc func stringPromise() -> AnyPromise {
|
|
||||||
return AnyPromise(stringPromise())
|
|
||||||
}
|
|
||||||
@objc func barPromise() -> AnyPromise {
|
|
||||||
return AnyPromise(barPromise())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If we built this and opened our generated header, we would now see:
|
|
||||||
|
|
||||||
```objc
|
|
||||||
@interface Foo
|
|
||||||
- (AnyPromise *)stringPromise;
|
|
||||||
- (AnyPromise *)barPromise;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface Bar
|
|
||||||
@end
|
|
||||||
```
|
|
||||||
|
|
||||||
Perfect.
|
|
||||||
|
|
||||||
Note that AnyPromise can only bridge objects that conform to `AnyObject` or derive from `NSObject`. This is a limitation of Objective-C.
|
|
||||||
|
|
@@ -1,13 +0,0 @@
|
|||||||
# Contents
|
|
||||||
|
|
||||||
* [README](/README.md)
|
|
||||||
* Handbook
|
|
||||||
* [Getting Started](GettingStarted.md)
|
|
||||||
* [Promises: Common Patterns](CommonPatterns.md)
|
|
||||||
* [Frequently Asked Questions](FAQ.md)
|
|
||||||
* Manual
|
|
||||||
* [Installation Guide](Installation.md)
|
|
||||||
* [Objective-C Guide](ObjectiveC.md)
|
|
||||||
* [Troubleshooting](Troubleshooting.md)
|
|
||||||
* [Appendix](Appendix.md)
|
|
||||||
* [API Reference](https://promisekit.org/reference/)
|
|
@@ -1,260 +0,0 @@
|
|||||||
# Troubleshooting
|
|
||||||
|
|
||||||
## Compilation errors
|
|
||||||
|
|
||||||
99% of compilation issues involving PromiseKit can be addressed or diagnosed by one of the fixes below.
|
|
||||||
|
|
||||||
### Check your handler
|
|
||||||
|
|
||||||
```swift
|
|
||||||
return firstly {
|
|
||||||
URLSession.shared.dataTask(.promise, with: url)
|
|
||||||
}.compactMap {
|
|
||||||
JSONSerialization.jsonObject(with: $0.data) as? [String: Any]
|
|
||||||
}.then { dict in
|
|
||||||
User(dict: dict)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Swift (unhelpfully) says:
|
|
||||||
|
|
||||||
> Cannot convert value of type '([String : Any]) -> User' to expected argument type '([String : Any]) -> _'
|
|
||||||
|
|
||||||
What’s the real problem? `then` *must* return a `Promise`, and you're trying to return something else. What you really want is `map`:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
return firstly {
|
|
||||||
URLSession.shared.dataTask(.promise, with: url)
|
|
||||||
}.compactMap {
|
|
||||||
JSONSerialization.jsonObject(with: $0.data) as? [String: Any]
|
|
||||||
}.map { dict in
|
|
||||||
User(dict: dict)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Specify closure parameters **and** return type
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
return firstly {
|
|
||||||
foo()
|
|
||||||
}.then { user in
|
|
||||||
//…
|
|
||||||
return bar()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This code may compile if you specify the type of `user`:
|
|
||||||
|
|
||||||
|
|
||||||
```swift
|
|
||||||
return firstly {
|
|
||||||
foo()
|
|
||||||
}.then { (user: User) in
|
|
||||||
//…
|
|
||||||
return bar()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If it still doesn't compile, perhaps you need to specify the return type, too:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
return firstly {
|
|
||||||
foo()
|
|
||||||
}.then { (user: User) -> Promise<Bar> in
|
|
||||||
//…
|
|
||||||
return bar()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
We have made great effort to reduce the need for explicit typing in PromiseKit 6,
|
|
||||||
but as with all Swift functions that return a generic type (e.g., `Array.map`),
|
|
||||||
you may need to explicitly tell Swift what a closure returns if the closure's body is
|
|
||||||
longer than one line.
|
|
||||||
|
|
||||||
> *Tip*: Sometimes you can force a one-liner by using semicolons.
|
|
||||||
|
|
||||||
|
|
||||||
### Acknowledge all incoming closure parameters
|
|
||||||
|
|
||||||
Swift does not permit you to silently ignore a closure's parameters. For example, this code:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func _() -> Promise<Void> {
|
|
||||||
return firstly {
|
|
||||||
proc.launch(.promise) // proc: Foundation.Process
|
|
||||||
}.then {
|
|
||||||
when(fulfilled: p1, p2) // both p1 & p2 are `Promise<Void>`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Fails to compile with the error:
|
|
||||||
|
|
||||||
Cannot invoke 'then' with an argument list of type '(() -> _)
|
|
||||||
|
|
||||||
What's the problem? Well, `Process.launch(.promise)` returns
|
|
||||||
`Promise<(String, String)>`, and we are ignoring this value in our `then` closure.
|
|
||||||
If we’d referenced `$0` or named the parameter, Swift would have been satisfied.
|
|
||||||
|
|
||||||
Assuming that we really do want to ignore the argument, the fix is to explicitly
|
|
||||||
acknowledge its existence by assigning it the name "_". That's Swift-ese for "I
|
|
||||||
know there's a value here, but I'm ignoring it."
|
|
||||||
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func _() -> Promise<Void> {
|
|
||||||
return firstly {
|
|
||||||
proc.launch(.promise)
|
|
||||||
}.then { _ in
|
|
||||||
when(fulfilled: p1, p2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In this situation, you won't always receive an error message that's as clear as the
|
|
||||||
one shown above. Sometimes, a missing closure parameter sends Swift scurrying off
|
|
||||||
into type inference limbo. When it finally concludes that there's no way for it to make
|
|
||||||
all the inferred types work together, it may end up assigning blame to some other
|
|
||||||
closure entirely and giving you an error message that makes no sense at all.
|
|
||||||
|
|
||||||
When faced with this kind of enigmatic complaint, a good rule of thumb is to
|
|
||||||
double-check your argument and return types carefully. If everything looks OK,
|
|
||||||
temporarily add explicit type information as shown above, just to rule
|
|
||||||
out mis-inference as a possible cause.
|
|
||||||
|
|
||||||
### Try moving code to a temporary inline function
|
|
||||||
|
|
||||||
Try taking the code out of a closure and putting it in a standalone function. Now Swift
|
|
||||||
will give you the *real* error message. For example:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func doStuff() {
|
|
||||||
firstly {
|
|
||||||
foo()
|
|
||||||
}.then {
|
|
||||||
let bar = bar()
|
|
||||||
let baz = baz()
|
|
||||||
when(fulfilled: bar, baz)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Becomes:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func doStuff() {
|
|
||||||
func fluff() -> Promise<…> {
|
|
||||||
let bar = bar()
|
|
||||||
let baz = baz()
|
|
||||||
when(fulfilled: bar, baz)
|
|
||||||
}
|
|
||||||
|
|
||||||
firstly {
|
|
||||||
foo()
|
|
||||||
}.then {
|
|
||||||
fluff()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
An *inline* function like this is all you need. Here, the problem is that you
|
|
||||||
forgot to mark the last line of the closure with an explicit `return`. It's required
|
|
||||||
here because the closure is longer than one line.
|
|
||||||
|
|
||||||
|
|
||||||
## You copied code off the Internet that doesn’t work
|
|
||||||
|
|
||||||
Swift has changed a lot over the years and so PromiseKit has had to change to keep
|
|
||||||
up. The code you copied is probably for an older PromiseKit. *Read the definitions of the
|
|
||||||
functions.* It's easy to do this in Xcode by option-clicking or command-clicking function names.
|
|
||||||
All PromiseKit functions are documented and provide examples.
|
|
||||||
|
|
||||||
## "Context type for closure argument expects 1 argument, which cannot be implicitly ignored"
|
|
||||||
|
|
||||||
You have a `then`; you want a `done`.
|
|
||||||
|
|
||||||
## "Missing argument for parameter #1 in call"
|
|
||||||
|
|
||||||
This is part of Swift 4’s “tuplegate”.
|
|
||||||
|
|
||||||
You must specify your `Void` parameter:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
seal.fulfill(())
|
|
||||||
```
|
|
||||||
|
|
||||||
Yes: we hope they revert this change in Swift 5 too.
|
|
||||||
|
|
||||||
## Other issues
|
|
||||||
|
|
||||||
### `Pending Promise Deallocated!`
|
|
||||||
|
|
||||||
If you see this warning, you have a path in your `Promise` initializer that allows
|
|
||||||
the promise to escape without being sealed:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
Promise<String> { seal in
|
|
||||||
task { value, error in
|
|
||||||
if let value = value as? String {
|
|
||||||
seal.fulfill(value)
|
|
||||||
} else if let error = error {
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
There are two missing paths here, and if either occurs, the promise will soon be
|
|
||||||
deallocated without resolving. This will manifest itself as a bug in your app,
|
|
||||||
probably the awful infinite spinner.
|
|
||||||
|
|
||||||
So let’s be thorough:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
Promise<String> { seal in
|
|
||||||
task { value, error in
|
|
||||||
if let value = value as? String {
|
|
||||||
fulfill(value)
|
|
||||||
} else if let error = error {
|
|
||||||
reject(error)
|
|
||||||
} else if value != nil {
|
|
||||||
reject(MyError.valueNotString)
|
|
||||||
} else {
|
|
||||||
// should never happen, but we have an `PMKError` for task being called with `nil`, `nil`
|
|
||||||
reject(PMKError.invalidCallingConvention)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If this seems tedious, it shouldn’t. You would have to be this thorough without promises, too.
|
|
||||||
The difference is that without promises, you wouldn’t get a warning in the console notifying
|
|
||||||
you of your mistake!
|
|
||||||
|
|
||||||
### Slow compilation / compiler cannot solve in reasonable time
|
|
||||||
|
|
||||||
Add return types to your closures.
|
|
||||||
|
|
||||||
### My promise never resolves
|
|
||||||
|
|
||||||
Check to be sure that your asynchronous task even *starts*. You’d be surprised how
|
|
||||||
often this is the cause.
|
|
||||||
|
|
||||||
For example, if you are using `URLSession` without our extension (but
|
|
||||||
don’t do that; *use* our extension! we know all the pitfalls), did you forget
|
|
||||||
to call `resume` on the task? If so, the task never actually starts, and so of
|
|
||||||
course it never finishes, either.
|
|
||||||
|
|
||||||
### `Result of call to 'done(on:_:)' is unused`, `Result of call to 'then(on:_:)' is unused`
|
|
||||||
|
|
||||||
PromiseKit deliberately avoids the `@discardableResult` annotation because the
|
|
||||||
unused result warning is a hint that you have not handled the error in your
|
|
||||||
chain. So do one of these:
|
|
||||||
|
|
||||||
1. Add a `catch`
|
|
||||||
2. `return` the promise (thus punting the error handling to the caller)
|
|
||||||
3. Use `cauterize()` to silence the warning.
|
|
||||||
|
|
||||||
Obviously, do 1 or 2 in preference to 3.
|
|
@@ -1,5 +0,0 @@
|
|||||||
*.xcodeproj/**/xcuserdata/
|
|
||||||
*.xcscmblueprint
|
|
||||||
/Carthage
|
|
||||||
/.build
|
|
||||||
.DS_Store
|
|
@@ -1,25 +0,0 @@
|
|||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- {osx_image: xcode8.3, env: 'SWFT=3.1 DST="OS=10.3.1,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=3.2 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=3.3 DST="OS=11.4,name=iPhone 5s"'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=3.4 DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=4.0 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=4.1 DST="OS=11.4,name=iPhone 5s" TEST=1'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=4.2 DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- Carthage
|
|
||||||
before_install:
|
|
||||||
- carthage bootstrap --cache-builds --no-use-binaries --platform iOS --verbose
|
|
||||||
install:
|
|
||||||
- xcodebuild -scheme PMKAVFoundation -target PMKAVFoundation -quiet -destination "$DST" build SWIFT_VERSION=$SWFT SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
- if [[ $TEST == "1" ]]; then
|
|
||||||
xcodebuild -scheme PMKAVFoundation -target PMKAVTests -quiet -destination "$DST" build;
|
|
||||||
fi
|
|
||||||
script:
|
|
||||||
- if [[ $TEST == "1" ]]; then
|
|
||||||
xcodebuild -scheme PMKAVFoundation -quiet -destination "$DST" test;
|
|
||||||
fi
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" ~> 6.0
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" "6.3.3"
|
|
@@ -1,7 +0,0 @@
|
|||||||
// Created by Kevin Ballard on 12/14/15.
|
|
||||||
// Copyright © 2015 Postmates. All rights reserved.
|
|
||||||
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SRCROOT)/Carthage/Build/Mac/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphone*] = $(SRCROOT)/Carthage/Build/iOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=watch*] = $(SRCROOT)/Carthage/Build/watchOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=appletv*] = $(SRCROOT)/Carthage/Build/tvOS/ $(inherited)
|
|
@@ -1,24 +0,0 @@
|
|||||||
<?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>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>FMWK</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
||||||
<key>NSPrincipalClass</key>
|
|
||||||
<string></string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,453 +0,0 @@
|
|||||||
// !$*UTF8*$!
|
|
||||||
{
|
|
||||||
archiveVersion = 1;
|
|
||||||
classes = {
|
|
||||||
};
|
|
||||||
objectVersion = 46;
|
|
||||||
objects = {
|
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKAVFoundation.framework */; };
|
|
||||||
63DD7EF81D7E7411000F279D /* TestAVFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 63DD7EF61D7E7411000F279D /* TestAVFoundation.m */; };
|
|
||||||
63DD7EF91D7E7411000F279D /* TestAVFoundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DD7EF71D7E7411000F279D /* TestAVFoundation.swift */; };
|
|
||||||
63DD7EFD1D7E7419000F279D /* AVAudioSession+AnyPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 63DD7EFA1D7E7419000F279D /* AVAudioSession+AnyPromise.h */; };
|
|
||||||
63DD7EFE1D7E7419000F279D /* AVAudioSession+AnyPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 63DD7EFB1D7E7419000F279D /* AVAudioSession+AnyPromise.m */; };
|
|
||||||
63DD7EFF1D7E7419000F279D /* AVAudioSession+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DD7EFC1D7E7419000F279D /* AVAudioSession+Promise.swift */; };
|
|
||||||
/* End PBXBuildFile section */
|
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
|
||||||
63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 63C7FFA61D5BEE09003BAE60;
|
|
||||||
remoteInfo = PMKFoundation;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
|
||||||
63167B891D5C23B4007A96B0 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
|
|
||||||
63BF28101D5C257100F62C66 /* Carthage.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Carthage.xcconfig; sourceTree = "<group>"; };
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAVFoundation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PMKAVFoundation.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKAVTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKAVTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63DD7EF61D7E7411000F279D /* TestAVFoundation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestAVFoundation.m; path = Tests/TestAVFoundation.m; sourceTree = SOURCE_ROOT; };
|
|
||||||
63DD7EF71D7E7411000F279D /* TestAVFoundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestAVFoundation.swift; path = Tests/TestAVFoundation.swift; sourceTree = SOURCE_ROOT; };
|
|
||||||
63DD7EFA1D7E7419000F279D /* AVAudioSession+AnyPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "AVAudioSession+AnyPromise.h"; path = "Sources/AVAudioSession+AnyPromise.h"; sourceTree = SOURCE_ROOT; };
|
|
||||||
63DD7EFB1D7E7419000F279D /* AVAudioSession+AnyPromise.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "AVAudioSession+AnyPromise.m"; path = "Sources/AVAudioSession+AnyPromise.m"; sourceTree = SOURCE_ROOT; };
|
|
||||||
63DD7EFC1D7E7419000F279D /* AVAudioSession+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "AVAudioSession+Promise.swift"; path = "Sources/AVAudioSession+Promise.swift"; sourceTree = SOURCE_ROOT; };
|
|
||||||
/* End PBXFileReference section */
|
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAVFoundation.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
|
||||||
63C7FF9D1D5BEE09003BAE60 = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63167B891D5C23B4007A96B0 /* Cartfile */,
|
|
||||||
63BF28101D5C257100F62C66 /* Carthage.xcconfig */,
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */,
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */,
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */,
|
|
||||||
);
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAVFoundation.framework */,
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKAVTests.xctest */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63DD7EFA1D7E7419000F279D /* AVAudioSession+AnyPromise.h */,
|
|
||||||
63DD7EFB1D7E7419000F279D /* AVAudioSession+AnyPromise.m */,
|
|
||||||
63DD7EFC1D7E7419000F279D /* AVAudioSession+Promise.swift */,
|
|
||||||
);
|
|
||||||
path = Sources;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63DD7EF61D7E7411000F279D /* TestAVFoundation.m */,
|
|
||||||
63DD7EF71D7E7411000F279D /* TestAVFoundation.swift */,
|
|
||||||
);
|
|
||||||
path = Tests;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */ = {
|
|
||||||
isa = PBXHeadersBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63DD7EFD1D7E7419000F279D /* AVAudioSession+AnyPromise.h in Headers */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXHeadersBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAVFoundation */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAVFoundation" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = PMKAVFoundation;
|
|
||||||
productName = "PMK+UIKit";
|
|
||||||
productReference = 63C7FFA71D5BEE09003BAE60 /* PMKAVFoundation.framework */;
|
|
||||||
productType = "com.apple.product-type.framework";
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKAVTests */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKAVTests" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */,
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */,
|
|
||||||
638F9B161D5EEEDC00717B37 /* Embed Carthage Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = PMKAVTests;
|
|
||||||
productName = PMKTests/NS;
|
|
||||||
productReference = 63C7FFF21D5C020D003BAE60 /* PMKAVTests.xctest */;
|
|
||||||
productType = "com.apple.product-type.bundle.unit-test";
|
|
||||||
};
|
|
||||||
/* End PBXNativeTarget section */
|
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
|
||||||
63C7FF9E1D5BEE09003BAE60 /* Project object */ = {
|
|
||||||
isa = PBXProject;
|
|
||||||
attributes = {
|
|
||||||
LastSwiftUpdateCheck = 0800;
|
|
||||||
LastUpgradeCheck = 1000;
|
|
||||||
ORGANIZATIONNAME = "Max Howell";
|
|
||||||
TargetAttributes = {
|
|
||||||
63C7FFA61D5BEE09003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildConfigurationList = 63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAVFoundation" */;
|
|
||||||
compatibilityVersion = "Xcode 3.2";
|
|
||||||
developmentRegion = English;
|
|
||||||
hasScannedForEncodings = 0;
|
|
||||||
knownRegions = (
|
|
||||||
en,
|
|
||||||
);
|
|
||||||
mainGroup = 63C7FF9D1D5BEE09003BAE60;
|
|
||||||
productRefGroup = 63C7FFA81D5BEE09003BAE60 /* Products */;
|
|
||||||
projectDirPath = "";
|
|
||||||
projectRoot = "";
|
|
||||||
targets = (
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAVFoundation */,
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKAVTests */,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
/* End PBXProject section */
|
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
638F9B161D5EEEDC00717B37 /* Embed Carthage Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
PromiseKit,
|
|
||||||
);
|
|
||||||
name = "Embed Carthage Frameworks";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "case \"$PLATFORM_NAME\" in\nmacosx) plat=Mac;;\niphone*) plat=iOS;;\nwatch*) plat=watchOS;;\nappletv*) plat=tvOS;;\n*) echo \"error: Unknown PLATFORM_NAME: $PLATFORM_NAME\"; exit 1;;\nesac\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nframework=$(basename \"${!VAR}\")\nexport SCRIPT_INPUT_FILE_$n=\"$SRCROOT\"/Carthage/Build/$plat/\"$framework\".framework\ndone\n\n/usr/local/bin/carthage copy-frameworks || exit\n\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nsource=${!VAR}.dSYM\ndest=${BUILT_PRODUCTS_DIR}/$(basename \"$source\")\nditto \"$source\" \"$dest\" || exit\ndone";
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63DD7EFF1D7E7419000F279D /* AVAudioSession+Promise.swift in Sources */,
|
|
||||||
63DD7EFE1D7E7419000F279D /* AVAudioSession+AnyPromise.m in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63DD7EF81D7E7411000F279D /* TestAVFoundation.m in Sources */,
|
|
||||||
63DD7EF91D7E7411000F279D /* TestAVFoundation.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 63C7FFA61D5BEE09003BAE60 /* PMKAVFoundation */;
|
|
||||||
targetProxy = 63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63BF28101D5C257100F62C66 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
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",
|
|
||||||
"$(inherited)",
|
|
||||||
);
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63BF28101D5C257100F62C66 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
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;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Accounts;
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Accounts;
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
|
||||||
63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAVFoundation" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAVFoundation" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKAVTests" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */,
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
|
||||||
};
|
|
||||||
rootObject = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "self:/Users/mxcl/Dropbox/Source/PMKX/AVFoundation/PMKAVFoundation.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,113 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Scheme
|
|
||||||
LastUpgradeVersion = "1000"
|
|
||||||
version = "1.3">
|
|
||||||
<BuildAction
|
|
||||||
parallelizeBuildables = "YES"
|
|
||||||
buildImplicitDependencies = "YES">
|
|
||||||
<BuildActionEntries>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "NO"
|
|
||||||
buildForProfiling = "NO"
|
|
||||||
buildForArchiving = "NO"
|
|
||||||
buildForAnalyzing = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKAVTests.xctest"
|
|
||||||
BlueprintName = "PMKAVTests"
|
|
||||||
ReferencedContainer = "container:PMKAVFoundation.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "NO"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAVFoundation.framework"
|
|
||||||
BlueprintName = "PMKAVFoundation"
|
|
||||||
ReferencedContainer = "container:PMKAVFoundation.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
||||||
<Testables>
|
|
||||||
<TestableReference
|
|
||||||
skipped = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKAVTests.xctest"
|
|
||||||
BlueprintName = "PMKAVTests"
|
|
||||||
ReferencedContainer = "container:PMKAVFoundation.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</TestableReference>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAVFoundation.framework"
|
|
||||||
BlueprintName = "PMKAVFoundation"
|
|
||||||
ReferencedContainer = "container:PMKAVFoundation.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
|
||||||
<LaunchAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
launchStyle = "0"
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
|
||||||
debugDocumentVersioning = "YES"
|
|
||||||
debugServiceExtension = "internal"
|
|
||||||
allowLocationSimulation = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAVFoundation.framework"
|
|
||||||
BlueprintName = "PMKAVFoundation"
|
|
||||||
ReferencedContainer = "container:PMKAVFoundation.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
|
||||||
<ProfileAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
debugDocumentVersioning = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAVFoundation.framework"
|
|
||||||
BlueprintName = "PMKAVFoundation"
|
|
||||||
ReferencedContainer = "container:PMKAVFoundation.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
</ProfileAction>
|
|
||||||
<AnalyzeAction
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
</AnalyzeAction>
|
|
||||||
<ArchiveAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
revealArchiveInOrganizer = "YES">
|
|
||||||
</ArchiveAction>
|
|
||||||
</Scheme>
|
|
@@ -1,34 +0,0 @@
|
|||||||
# PromiseKit AVFoundation Extensions ![Build Status]
|
|
||||||
|
|
||||||
This project adds promises to Apple’s AVFoundation framework.
|
|
||||||
|
|
||||||
## CococaPods
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
pod "PromiseKit/AVFoundation" ~> 6.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into `PromiseKit.framework` thus nothing else is needed.
|
|
||||||
|
|
||||||
## Carthage
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
github "PromiseKit/AVFoundation" ~> 3.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into their own framework:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// swift
|
|
||||||
import PromiseKit
|
|
||||||
import PMKAVFoundation
|
|
||||||
```
|
|
||||||
|
|
||||||
```objc
|
|
||||||
// objc
|
|
||||||
@import PromiseKit;
|
|
||||||
@import PMKAVFoundation;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
[Build Status]: https://travis-ci.org/PromiseKit/AVFoundation.svg?branch=master
|
|
@@ -1,30 +0,0 @@
|
|||||||
//
|
|
||||||
// AVFoundation+AnyPromise.h
|
|
||||||
//
|
|
||||||
// Created by Matthew Loseke on 6/21/14.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
|
||||||
#import <PromiseKit/AnyPromise.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
To import the `AVAudioSession` category:
|
|
||||||
|
|
||||||
use_frameworks!
|
|
||||||
pod "PromiseKit/AVFoundation"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
#import <PromiseKit/PromiseKit.h>
|
|
||||||
*/
|
|
||||||
@interface AVAudioSession (PromiseKit)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Wraps `-requestRecordPermission:`, thens the `BOOL granted` parameter
|
|
||||||
passed to the wrapped completion block. This promise cannot fail.
|
|
||||||
|
|
||||||
@see requestRecordPermission:
|
|
||||||
*/
|
|
||||||
- (AnyPromise *)requestRecordPermission;
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,21 +0,0 @@
|
|||||||
//
|
|
||||||
// AVAudioSession+PromiseKit.m
|
|
||||||
//
|
|
||||||
// Created by Matthew Loseke on 6/21/14.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "AVAudioSession+AnyPromise.h"
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
|
|
||||||
@implementation AVAudioSession (PromiseKit)
|
|
||||||
|
|
||||||
- (AnyPromise *)requestRecordPermission {
|
|
||||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
|
||||||
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
|
|
||||||
resolve(@(granted));
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,21 +0,0 @@
|
|||||||
import AVFoundation
|
|
||||||
import Foundation
|
|
||||||
#if !PMKCocoaPods
|
|
||||||
import PromiseKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
To import the `AVAudioSession` category:
|
|
||||||
|
|
||||||
use_frameworks!
|
|
||||||
pod "PromiseKit/AVFoundation"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
import PromiseKit
|
|
||||||
*/
|
|
||||||
extension AVAudioSession {
|
|
||||||
public func requestRecordPermission() -> Guarantee<Bool> {
|
|
||||||
return Guarantee(resolver: requestRecordPermission)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
#import "AVAudioSession+AnyPromise.h"
|
|
||||||
@import AVFoundation;
|
|
||||||
@import XCTest;
|
|
||||||
|
|
||||||
@implementation Test_AVAudioSession_ObjC: XCTestCase
|
|
||||||
|
|
||||||
- (void)test {
|
|
||||||
id ex = [self expectationWithDescription:@""];
|
|
||||||
|
|
||||||
[[AVAudioSession new] requestRecordPermission].then(^{
|
|
||||||
[ex fulfill];
|
|
||||||
});
|
|
||||||
|
|
||||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,24 +0,0 @@
|
|||||||
import PMKAVFoundation
|
|
||||||
import AVFoundation
|
|
||||||
import PromiseKit
|
|
||||||
import XCTest
|
|
||||||
|
|
||||||
class Test_AVAudioSession_Swift: XCTestCase {
|
|
||||||
func test() {
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
|
|
||||||
AVAudioSession().requestRecordPermission().done { _ in
|
|
||||||
ex.fulfill()
|
|
||||||
}
|
|
||||||
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testNotAmbiguous() {
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
AVAudioSession().requestRecordPermission { _ in
|
|
||||||
ex.fulfill()
|
|
||||||
}
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
*.xcodeproj/**/xcuserdata/
|
|
||||||
*.xcscmblueprint
|
|
||||||
/Carthage
|
|
||||||
/.build
|
|
||||||
.DS_Store
|
|
@@ -1,38 +0,0 @@
|
|||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- {osx_image: xcode8.3, env: 'SWFT=3.1 PLAT=macOS DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode8.3, env: 'SWFT=3.1 PLAT=iOS DST="OS=10.3.1,name=iPhone SE"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=3.2 PLAT=macOS DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=3.2 PLAT=iOS DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=3.3 PLAT=macOS DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=3.3 PLAT=iOS DST="OS=11.4,name=iPhone 5s"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=3.4 PLAT=macOS DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=3.4 PLAT=iOS DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=macOS DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=iOS DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=4.1 PLAT=macOS DST="arch=x86_64" TEST=1'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=4.1 PLAT=iOS DST="OS=11.4,name=iPhone 5s" TEST=1'}
|
|
||||||
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=4.2 PLAT=macOS DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=4.2 PLAT=iOS DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- Carthage
|
|
||||||
before_install:
|
|
||||||
- carthage bootstrap --cache-builds --no-use-binaries --platform $PLAT --verbose
|
|
||||||
install:
|
|
||||||
- xcodebuild -scheme PMKAccounts -target PMKAccounts -quiet -destination "$DST" SWIFT_VERSION=$SWFT SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
- if [[ $TEST == "1" ]]; then
|
|
||||||
xcodebuild -scheme PMKAccounts -target PMKACTests -quiet -destination "$DST" build;
|
|
||||||
fi
|
|
||||||
script:
|
|
||||||
- if [[ $TEST == "1" ]]; then
|
|
||||||
xcodebuild -scheme PMKAccounts -quiet -destination "$DST" test;
|
|
||||||
fi
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" ~> 6.0
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" "6.3.3"
|
|
@@ -1,7 +0,0 @@
|
|||||||
// Created by Kevin Ballard on 12/14/15.
|
|
||||||
// Copyright © 2015 Postmates. All rights reserved.
|
|
||||||
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SRCROOT)/Carthage/Build/Mac/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphone*] = $(SRCROOT)/Carthage/Build/iOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=watch*] = $(SRCROOT)/Carthage/Build/watchOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=appletv*] = $(SRCROOT)/Carthage/Build/tvOS/ $(inherited)
|
|
@@ -1,24 +0,0 @@
|
|||||||
<?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>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>FMWK</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
||||||
<key>NSPrincipalClass</key>
|
|
||||||
<string></string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,447 +0,0 @@
|
|||||||
// !$*UTF8*$!
|
|
||||||
{
|
|
||||||
archiveVersion = 1;
|
|
||||||
classes = {
|
|
||||||
};
|
|
||||||
objectVersion = 46;
|
|
||||||
objects = {
|
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
|
||||||
63167B841D5C2332007A96B0 /* ACAccountStore+AnyPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 63167B811D5C2332007A96B0 /* ACAccountStore+AnyPromise.h */; };
|
|
||||||
63167B851D5C2332007A96B0 /* ACAccountStore+AnyPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 63167B821D5C2332007A96B0 /* ACAccountStore+AnyPromise.m */; };
|
|
||||||
63167B861D5C2332007A96B0 /* ACAccountStore+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63167B831D5C2332007A96B0 /* ACAccountStore+Promise.swift */; };
|
|
||||||
63167B881D5C233C007A96B0 /* TestAccounts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63167B871D5C233C007A96B0 /* TestAccounts.swift */; };
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAccounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKAccounts.framework */; };
|
|
||||||
/* End PBXBuildFile section */
|
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
|
||||||
63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 63C7FFA61D5BEE09003BAE60;
|
|
||||||
remoteInfo = PMKFoundation;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
|
||||||
63167B811D5C2332007A96B0 /* ACAccountStore+AnyPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ACAccountStore+AnyPromise.h"; path = "Sources/ACAccountStore+AnyPromise.h"; sourceTree = SOURCE_ROOT; };
|
|
||||||
63167B821D5C2332007A96B0 /* ACAccountStore+AnyPromise.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "ACAccountStore+AnyPromise.m"; path = "Sources/ACAccountStore+AnyPromise.m"; sourceTree = SOURCE_ROOT; };
|
|
||||||
63167B831D5C2332007A96B0 /* ACAccountStore+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "ACAccountStore+Promise.swift"; path = "Sources/ACAccountStore+Promise.swift"; sourceTree = SOURCE_ROOT; };
|
|
||||||
63167B871D5C233C007A96B0 /* TestAccounts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestAccounts.swift; path = Tests/TestAccounts.swift; sourceTree = SOURCE_ROOT; };
|
|
||||||
63167B891D5C23B4007A96B0 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
|
|
||||||
63BF28101D5C257100F62C66 /* Carthage.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Carthage.xcconfig; sourceTree = "<group>"; };
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAccounts.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PMKAccounts.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKACTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKACTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
/* End PBXFileReference section */
|
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAccounts.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
|
||||||
63C7FF9D1D5BEE09003BAE60 = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63167B891D5C23B4007A96B0 /* Cartfile */,
|
|
||||||
63BF28101D5C257100F62C66 /* Carthage.xcconfig */,
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */,
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */,
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */,
|
|
||||||
);
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAccounts.framework */,
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKACTests.xctest */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63167B811D5C2332007A96B0 /* ACAccountStore+AnyPromise.h */,
|
|
||||||
63167B821D5C2332007A96B0 /* ACAccountStore+AnyPromise.m */,
|
|
||||||
63167B831D5C2332007A96B0 /* ACAccountStore+Promise.swift */,
|
|
||||||
);
|
|
||||||
path = Sources;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63167B871D5C233C007A96B0 /* TestAccounts.swift */,
|
|
||||||
);
|
|
||||||
path = Tests;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */ = {
|
|
||||||
isa = PBXHeadersBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63167B841D5C2332007A96B0 /* ACAccountStore+AnyPromise.h in Headers */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXHeadersBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAccounts */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAccounts" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = PMKAccounts;
|
|
||||||
productName = "PMK+UIKit";
|
|
||||||
productReference = 63C7FFA71D5BEE09003BAE60 /* PMKAccounts.framework */;
|
|
||||||
productType = "com.apple.product-type.framework";
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKACTests */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKACTests" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */,
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */,
|
|
||||||
638F9B161D5EEEDC00717B37 /* Embed Carthage Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = PMKACTests;
|
|
||||||
productName = PMKTests/NS;
|
|
||||||
productReference = 63C7FFF21D5C020D003BAE60 /* PMKACTests.xctest */;
|
|
||||||
productType = "com.apple.product-type.bundle.unit-test";
|
|
||||||
};
|
|
||||||
/* End PBXNativeTarget section */
|
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
|
||||||
63C7FF9E1D5BEE09003BAE60 /* Project object */ = {
|
|
||||||
isa = PBXProject;
|
|
||||||
attributes = {
|
|
||||||
LastSwiftUpdateCheck = 0800;
|
|
||||||
LastUpgradeCheck = 1000;
|
|
||||||
ORGANIZATIONNAME = "Max Howell";
|
|
||||||
TargetAttributes = {
|
|
||||||
63C7FFA61D5BEE09003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 1000;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 1000;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildConfigurationList = 63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAccounts" */;
|
|
||||||
compatibilityVersion = "Xcode 3.2";
|
|
||||||
developmentRegion = English;
|
|
||||||
hasScannedForEncodings = 0;
|
|
||||||
knownRegions = (
|
|
||||||
en,
|
|
||||||
);
|
|
||||||
mainGroup = 63C7FF9D1D5BEE09003BAE60;
|
|
||||||
productRefGroup = 63C7FFA81D5BEE09003BAE60 /* Products */;
|
|
||||||
projectDirPath = "";
|
|
||||||
projectRoot = "";
|
|
||||||
targets = (
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAccounts */,
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKACTests */,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
/* End PBXProject section */
|
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
638F9B161D5EEEDC00717B37 /* Embed Carthage Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
PromiseKit,
|
|
||||||
);
|
|
||||||
name = "Embed Carthage Frameworks";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "case \"$PLATFORM_NAME\" in\nmacosx) plat=Mac;;\niphone*) plat=iOS;;\nwatch*) plat=watchOS;;\nappletv*) plat=tvOS;;\n*) echo \"error: Unknown PLATFORM_NAME: $PLATFORM_NAME\"; exit 1;;\nesac\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nframework=$(basename \"${!VAR}\")\nexport SCRIPT_INPUT_FILE_$n=\"$SRCROOT\"/Carthage/Build/$plat/\"$framework\".framework\ndone\n\n/usr/local/bin/carthage copy-frameworks || exit\n\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nsource=${!VAR}.dSYM\ndest=${BUILT_PRODUCTS_DIR}/$(basename \"$source\")\nditto \"$source\" \"$dest\" || exit\ndone";
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63167B851D5C2332007A96B0 /* ACAccountStore+AnyPromise.m in Sources */,
|
|
||||||
63167B861D5C2332007A96B0 /* ACAccountStore+Promise.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63167B881D5C233C007A96B0 /* TestAccounts.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 63C7FFA61D5BEE09003BAE60 /* PMKAccounts */;
|
|
||||||
targetProxy = 63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63BF28101D5C257100F62C66 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
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",
|
|
||||||
"$(inherited)",
|
|
||||||
);
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63BF28101D5C257100F62C66 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
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;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Accounts;
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Accounts;
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
|
||||||
63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAccounts" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAccounts" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKACTests" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */,
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
|
||||||
};
|
|
||||||
rootObject = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "self:/Users/mxcl/Desktop/PMK+UIKit/PMKFoundation.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,113 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Scheme
|
|
||||||
LastUpgradeVersion = "1000"
|
|
||||||
version = "1.3">
|
|
||||||
<BuildAction
|
|
||||||
parallelizeBuildables = "YES"
|
|
||||||
buildImplicitDependencies = "YES">
|
|
||||||
<BuildActionEntries>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKACTests.xctest"
|
|
||||||
BlueprintName = "PMKACTests"
|
|
||||||
ReferencedContainer = "container:PMKAccounts.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAccounts.framework"
|
|
||||||
BlueprintName = "PMKAccounts"
|
|
||||||
ReferencedContainer = "container:PMKAccounts.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
||||||
<Testables>
|
|
||||||
<TestableReference
|
|
||||||
skipped = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKACTests.xctest"
|
|
||||||
BlueprintName = "PMKACTests"
|
|
||||||
ReferencedContainer = "container:PMKAccounts.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</TestableReference>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKACTests.xctest"
|
|
||||||
BlueprintName = "PMKACTests"
|
|
||||||
ReferencedContainer = "container:PMKAccounts.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
|
||||||
<LaunchAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
launchStyle = "0"
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
|
||||||
debugDocumentVersioning = "YES"
|
|
||||||
debugServiceExtension = "internal"
|
|
||||||
allowLocationSimulation = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKACTests.xctest"
|
|
||||||
BlueprintName = "PMKACTests"
|
|
||||||
ReferencedContainer = "container:PMKAccounts.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
|
||||||
<ProfileAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
debugDocumentVersioning = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKACTests.xctest"
|
|
||||||
BlueprintName = "PMKACTests"
|
|
||||||
ReferencedContainer = "container:PMKAccounts.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
</ProfileAction>
|
|
||||||
<AnalyzeAction
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
</AnalyzeAction>
|
|
||||||
<ArchiveAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
revealArchiveInOrganizer = "YES">
|
|
||||||
</ArchiveAction>
|
|
||||||
</Scheme>
|
|
@@ -1,34 +0,0 @@
|
|||||||
# PromiseKit Accounts Extensions ![Build Status]
|
|
||||||
|
|
||||||
This project adds promises to Apple’s Accounts framework.
|
|
||||||
|
|
||||||
## CococaPods
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
pod "PromiseKit/Accounts" ~> 6.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into `PromiseKit.framework` thus nothing else is needed.
|
|
||||||
|
|
||||||
## Carthage
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
github "PromiseKit/Accounts" ~> 3.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into their own framework:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// swift
|
|
||||||
import PromiseKit
|
|
||||||
import PMKAccounts
|
|
||||||
```
|
|
||||||
|
|
||||||
```objc
|
|
||||||
// objc
|
|
||||||
@import PromiseKit;
|
|
||||||
@import PMKAccounts;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
[Build Status]: https://travis-ci.org/PromiseKit/Accounts.svg?branch=master
|
|
@@ -1,66 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by merowing on 09/05/2014.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <PromiseKit/AnyPromise.h>
|
|
||||||
#import <Accounts/ACAccountStore.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
To import the `ACAccountStore` category:
|
|
||||||
|
|
||||||
use_frameworks!
|
|
||||||
pod "PromiseKit/Accounts"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
@import PromiseKit;
|
|
||||||
*/
|
|
||||||
@interface ACAccountStore (PromiseKit)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Obtains permission to access protected user properties.
|
|
||||||
|
|
||||||
@param type The account type.
|
|
||||||
|
|
||||||
@param options Can be nil.
|
|
||||||
|
|
||||||
@return A promise that resolves when the requested permissions have been
|
|
||||||
successfully obtained. The promise thens all accounts of the specified
|
|
||||||
type.
|
|
||||||
|
|
||||||
@see requestAccessToAccountsWithType:options:completion:
|
|
||||||
*/
|
|
||||||
- (AnyPromise *)requestAccessToAccountsWithType:(ACAccountType *)type options:(NSDictionary *)options NS_REFINED_FOR_SWIFT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Renews account credentials when the credentials are no longer valid.
|
|
||||||
|
|
||||||
@param account The account to renew credentials.
|
|
||||||
|
|
||||||
@return A promise that thens the `ACAccountCredentialRenewResult`.
|
|
||||||
*/
|
|
||||||
- (AnyPromise *)renewCredentialsForAccount:(ACAccount *)account NS_REFINED_FOR_SWIFT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Saves an account to the Accounts database.
|
|
||||||
|
|
||||||
@param account The account to save.
|
|
||||||
|
|
||||||
@return A promise that resolves when the account has been successfully
|
|
||||||
saved.
|
|
||||||
*/
|
|
||||||
- (AnyPromise *)saveAccount:(ACAccount *)account NS_REFINED_FOR_SWIFT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Removes an account from the account store.
|
|
||||||
|
|
||||||
@param account The account to remove.
|
|
||||||
|
|
||||||
@return A promise that resolves when the account has been successfully
|
|
||||||
removed.
|
|
||||||
*/
|
|
||||||
- (AnyPromise *)removeAccount:(ACAccount *)account NS_REFINED_FOR_SWIFT;
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,48 +0,0 @@
|
|||||||
#import "ACAccountStore+AnyPromise.h"
|
|
||||||
#import <PromiseKit/PromiseKit.h>
|
|
||||||
|
|
||||||
|
|
||||||
@implementation ACAccountStore (PromiseKit)
|
|
||||||
|
|
||||||
- (AnyPromise *)requestAccessToAccountsWithType:(ACAccountType *)type options:(NSDictionary *)options {
|
|
||||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
|
||||||
[self requestAccessToAccountsWithType:type options:options completion:^(BOOL granted, NSError *error) {
|
|
||||||
if (granted) {
|
|
||||||
resolve([self accountsWithAccountType:type]);
|
|
||||||
} else if (error) {
|
|
||||||
resolve(error);
|
|
||||||
} else {
|
|
||||||
error = [NSError errorWithDomain:PMKErrorDomain code:PMKAccessDeniedError userInfo:@{
|
|
||||||
NSLocalizedDescriptionKey: @"Access to the requested social service has been denied. Please enable access in your device settings."
|
|
||||||
}];
|
|
||||||
resolve(error);
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AnyPromise *)renewCredentialsForAccount:(ACAccount *)account {
|
|
||||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
|
||||||
[self renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
|
|
||||||
resolve(error ?: @(renewResult));
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AnyPromise *)saveAccount:(ACAccount *)account {
|
|
||||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
|
||||||
[self saveAccount:account withCompletionHandler:^(BOOL success, NSError *error) {
|
|
||||||
resolve(error);
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AnyPromise *)removeAccount:(ACAccount *)account {
|
|
||||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
|
||||||
[self removeAccount:account withCompletionHandler:^(BOOL success, NSError *error) {
|
|
||||||
resolve(error);
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,59 +0,0 @@
|
|||||||
import Accounts
|
|
||||||
#if !PMKCocoaPods
|
|
||||||
import PromiseKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
To import the `ACAccountStore` category:
|
|
||||||
|
|
||||||
use_frameworks!
|
|
||||||
pod "PromiseKit/ACAccountStore"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
import PromiseKit
|
|
||||||
*/
|
|
||||||
extension ACAccountStore {
|
|
||||||
/// Renews account credentials when the credentials are no longer valid.
|
|
||||||
public func renewCredentials(for account: ACAccount) -> Promise<ACAccountCredentialRenewResult> {
|
|
||||||
return Promise { renewCredentials(for: account, completion: $0.resolve) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Obtains permission to access protected user properties.
|
|
||||||
public func requestAccessToAccounts(with type: ACAccountType, options: [AnyHashable: Any]? = nil) -> Promise<Void> {
|
|
||||||
return Promise { seal in
|
|
||||||
requestAccessToAccounts(with: type, options: options, completion: { granted, error in
|
|
||||||
if granted {
|
|
||||||
seal.fulfill(())
|
|
||||||
} else if let error = error {
|
|
||||||
seal.reject(error)
|
|
||||||
} else {
|
|
||||||
seal.reject(PMKError.accessDenied)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Saves an account to the Accounts database.
|
|
||||||
public func saveAccount(_ account: ACAccount) -> Promise<Void> {
|
|
||||||
return Promise { saveAccount(account, withCompletionHandler: $0.resolve) }.asVoid()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes an account from the account store.
|
|
||||||
public func removeAccount(_ account: ACAccount) -> Promise<Void> {
|
|
||||||
return Promise { removeAccount(account, withCompletionHandler: $0.resolve) }.asVoid()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// PromiseKit ACAccountStore errors
|
|
||||||
public enum PMKError: Error, CustomStringConvertible {
|
|
||||||
/// The request for accounts access was denied.
|
|
||||||
case accessDenied
|
|
||||||
|
|
||||||
public var description: String {
|
|
||||||
switch self {
|
|
||||||
case .accessDenied:
|
|
||||||
return "Access to the requested social service has been denied. Please enable access in your device settings."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,80 +0,0 @@
|
|||||||
import PMKAccounts
|
|
||||||
import PromiseKit
|
|
||||||
import Accounts
|
|
||||||
import XCTest
|
|
||||||
|
|
||||||
class Test_ACAccountStore_Swift: XCTestCase {
|
|
||||||
var dummy: ACAccount { return ACAccount() }
|
|
||||||
|
|
||||||
func test_renewCredentialsForAccount() {
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
|
|
||||||
class MockAccountStore: ACAccountStore {
|
|
||||||
override func renewCredentials(for account: ACAccount!, completion: ACAccountStoreCredentialRenewalHandler!) {
|
|
||||||
completion(.renewed, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MockAccountStore().renewCredentials(for: dummy).done { result in
|
|
||||||
XCTAssertEqual(result, ACAccountCredentialRenewResult.renewed)
|
|
||||||
ex.fulfill()
|
|
||||||
}.catch {
|
|
||||||
XCTFail("\($0)")
|
|
||||||
}
|
|
||||||
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_requestAccessToAccountsWithType() {
|
|
||||||
class MockAccountStore: ACAccountStore {
|
|
||||||
override func requestAccessToAccounts(with accountType: ACAccountType!, options: [AnyHashable : Any]! = [:], completion: ACAccountStoreRequestAccessCompletionHandler!) {
|
|
||||||
completion(true, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
let store = MockAccountStore()
|
|
||||||
let type = store.accountType(withAccountTypeIdentifier: ACAccountTypeIdentifierFacebook)!
|
|
||||||
store.requestAccessToAccounts(with: type).done { _ in
|
|
||||||
ex.fulfill()
|
|
||||||
}.catch {
|
|
||||||
XCTFail("\($0)")
|
|
||||||
}
|
|
||||||
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_saveAccount() {
|
|
||||||
class MockAccountStore: ACAccountStore {
|
|
||||||
override func saveAccount(_ account: ACAccount!, withCompletionHandler completionHandler: ACAccountStoreSaveCompletionHandler!) {
|
|
||||||
completionHandler(true, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
MockAccountStore().saveAccount(dummy).done { _ in
|
|
||||||
ex.fulfill()
|
|
||||||
}.catch {
|
|
||||||
XCTFail("\($0)")
|
|
||||||
}
|
|
||||||
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_removeAccount() {
|
|
||||||
class MockAccountStore: ACAccountStore {
|
|
||||||
override func removeAccount(_ account: ACAccount!, withCompletionHandler completionHandler: ACAccountStoreSaveCompletionHandler!) {
|
|
||||||
completionHandler(true, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
MockAccountStore().removeAccount(dummy).done { _ in
|
|
||||||
ex.fulfill()
|
|
||||||
}.catch {
|
|
||||||
XCTFail("\($0)")
|
|
||||||
}
|
|
||||||
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
*.xcodeproj/**/xcuserdata/
|
|
||||||
*.xcscmblueprint
|
|
||||||
/Carthage
|
|
||||||
/.build
|
|
||||||
.DS_Store
|
|
@@ -1,25 +0,0 @@
|
|||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- {osx_image: xcode8.3, env: 'SWFT=3.1 DST="OS=10.3.1,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=3.2 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=3.3 DST="OS=11.4,name=iPhone 5s"'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=3.4 DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=4.0 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=4.1 DST="OS=11.4,name=iPhone 5s" TEST=1'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=4.2 DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- Carthage
|
|
||||||
before_install:
|
|
||||||
- carthage bootstrap --cache-builds --no-use-binaries --platform iOS --verbose
|
|
||||||
install:
|
|
||||||
- xcodebuild -scheme PMKAddressBook -target PMKAddressBook -quiet -destination "$DST" SWIFT_VERSION=$SWFT SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
- if [[ $TEST == "1" ]]; then
|
|
||||||
xcodebuild -scheme PMKAddressBook -target PMKABTests -quiet -destination "$DST" build;
|
|
||||||
fi
|
|
||||||
script:
|
|
||||||
- if [[ $TEST == "1" ]]; then
|
|
||||||
xcodebuild -scheme PMKAddressBook -quiet -destination "$DST" test;
|
|
||||||
fi
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" ~> 6.0
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" "6.3.3"
|
|
@@ -1,7 +0,0 @@
|
|||||||
// Created by Kevin Ballard on 12/14/15.
|
|
||||||
// Copyright © 2015 Postmates. All rights reserved.
|
|
||||||
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SRCROOT)/Carthage/Build/Mac/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphone*] = $(SRCROOT)/Carthage/Build/iOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=watch*] = $(SRCROOT)/Carthage/Build/watchOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=appletv*] = $(SRCROOT)/Carthage/Build/tvOS/ $(inherited)
|
|
@@ -1,24 +0,0 @@
|
|||||||
<?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>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>FMWK</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
||||||
<key>NSPrincipalClass</key>
|
|
||||||
<string></string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,439 +0,0 @@
|
|||||||
// !$*UTF8*$!
|
|
||||||
{
|
|
||||||
archiveVersion = 1;
|
|
||||||
classes = {
|
|
||||||
};
|
|
||||||
objectVersion = 46;
|
|
||||||
objects = {
|
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
|
||||||
63938C031D5C27AE00F4C165 /* ABAddressBookRequestAccess+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63938C021D5C27AE00F4C165 /* ABAddressBookRequestAccess+Promise.swift */; };
|
|
||||||
63938C091D5C27F600F4C165 /* TestAddressBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63938C081D5C27F600F4C165 /* TestAddressBook.swift */; };
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKAddressBook.framework */; };
|
|
||||||
/* End PBXBuildFile section */
|
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
|
||||||
63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 63C7FFA61D5BEE09003BAE60;
|
|
||||||
remoteInfo = PMKFoundation;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
|
||||||
63167B891D5C23B4007A96B0 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
|
|
||||||
63938C021D5C27AE00F4C165 /* ABAddressBookRequestAccess+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "ABAddressBookRequestAccess+Promise.swift"; path = "Sources/ABAddressBookRequestAccess+Promise.swift"; sourceTree = SOURCE_ROOT; };
|
|
||||||
63938C081D5C27F600F4C165 /* TestAddressBook.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestAddressBook.swift; path = Tests/TestAddressBook.swift; sourceTree = SOURCE_ROOT; };
|
|
||||||
63BF28101D5C257100F62C66 /* Carthage.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Carthage.xcconfig; sourceTree = "<group>"; };
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAddressBook.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PMKAddressBook.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKABTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKABTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
/* End PBXFileReference section */
|
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAddressBook.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
|
||||||
63C7FF9D1D5BEE09003BAE60 = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63167B891D5C23B4007A96B0 /* Cartfile */,
|
|
||||||
63BF28101D5C257100F62C66 /* Carthage.xcconfig */,
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */,
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */,
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */,
|
|
||||||
);
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAddressBook.framework */,
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKABTests.xctest */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63938C021D5C27AE00F4C165 /* ABAddressBookRequestAccess+Promise.swift */,
|
|
||||||
);
|
|
||||||
path = Sources;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63938C081D5C27F600F4C165 /* TestAddressBook.swift */,
|
|
||||||
);
|
|
||||||
path = Tests;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */ = {
|
|
||||||
isa = PBXHeadersBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXHeadersBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAddressBook */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAddressBook" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = PMKAddressBook;
|
|
||||||
productName = "PMK+UIKit";
|
|
||||||
productReference = 63C7FFA71D5BEE09003BAE60 /* PMKAddressBook.framework */;
|
|
||||||
productType = "com.apple.product-type.framework";
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKABTests */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKABTests" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */,
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */,
|
|
||||||
63EF83AD1D5FA940008748A6 /* Embed Carthage Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = PMKABTests;
|
|
||||||
productName = PMKTests/NS;
|
|
||||||
productReference = 63C7FFF21D5C020D003BAE60 /* PMKABTests.xctest */;
|
|
||||||
productType = "com.apple.product-type.bundle.unit-test";
|
|
||||||
};
|
|
||||||
/* End PBXNativeTarget section */
|
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
|
||||||
63C7FF9E1D5BEE09003BAE60 /* Project object */ = {
|
|
||||||
isa = PBXProject;
|
|
||||||
attributes = {
|
|
||||||
LastSwiftUpdateCheck = 0800;
|
|
||||||
LastUpgradeCheck = 1000;
|
|
||||||
ORGANIZATIONNAME = "Max Howell";
|
|
||||||
TargetAttributes = {
|
|
||||||
63C7FFA61D5BEE09003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildConfigurationList = 63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAddressBook" */;
|
|
||||||
compatibilityVersion = "Xcode 3.2";
|
|
||||||
developmentRegion = English;
|
|
||||||
hasScannedForEncodings = 0;
|
|
||||||
knownRegions = (
|
|
||||||
en,
|
|
||||||
);
|
|
||||||
mainGroup = 63C7FF9D1D5BEE09003BAE60;
|
|
||||||
productRefGroup = 63C7FFA81D5BEE09003BAE60 /* Products */;
|
|
||||||
projectDirPath = "";
|
|
||||||
projectRoot = "";
|
|
||||||
targets = (
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAddressBook */,
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKABTests */,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
/* End PBXProject section */
|
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
63EF83AD1D5FA940008748A6 /* Embed Carthage Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
PromiseKit,
|
|
||||||
);
|
|
||||||
name = "Embed Carthage Frameworks";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "case \"$PLATFORM_NAME\" in\nmacosx) plat=Mac;;\niphone*) plat=iOS;;\nwatch*) plat=watchOS;;\nappletv*) plat=tvOS;;\n*) echo \"error: Unknown PLATFORM_NAME: $PLATFORM_NAME\"; exit 1;;\nesac\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nframework=$(basename \"${!VAR}\")\nexport SCRIPT_INPUT_FILE_$n=\"$SRCROOT\"/Carthage/Build/$plat/\"$framework\".framework\ndone\n\n/usr/local/bin/carthage copy-frameworks || exit\n\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nsource=${!VAR}.dSYM\ndest=${BUILT_PRODUCTS_DIR}/$(basename \"$source\")\nditto \"$source\" \"$dest\" || exit\ndone";
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63938C031D5C27AE00F4C165 /* ABAddressBookRequestAccess+Promise.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63938C091D5C27F600F4C165 /* TestAddressBook.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 63C7FFA61D5BEE09003BAE60 /* PMKAddressBook */;
|
|
||||||
targetProxy = 63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63BF28101D5C257100F62C66 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
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",
|
|
||||||
"$(inherited)",
|
|
||||||
);
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63BF28101D5C257100F62C66 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
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;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.AddressBook;
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.AddressBook;
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
|
||||||
63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAddressBook" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAddressBook" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKABTests" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */,
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
|
||||||
};
|
|
||||||
rootObject = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "self:/Users/mxcl/Desktop/PMK+UIKit/PMKFoundation.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,99 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Scheme
|
|
||||||
LastUpgradeVersion = "1000"
|
|
||||||
version = "1.3">
|
|
||||||
<BuildAction
|
|
||||||
parallelizeBuildables = "YES"
|
|
||||||
buildImplicitDependencies = "YES">
|
|
||||||
<BuildActionEntries>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "NO"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAddressBook.framework"
|
|
||||||
BlueprintName = "PMKAddressBook"
|
|
||||||
ReferencedContainer = "container:PMKAddressBook.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
||||||
<Testables>
|
|
||||||
<TestableReference
|
|
||||||
skipped = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKABTests.xctest"
|
|
||||||
BlueprintName = "PMKABTests"
|
|
||||||
ReferencedContainer = "container:PMKAddressBook.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</TestableReference>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAddressBook.framework"
|
|
||||||
BlueprintName = "PMKAddressBook"
|
|
||||||
ReferencedContainer = "container:PMKAddressBook.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
|
||||||
<LaunchAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
launchStyle = "0"
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
|
||||||
debugDocumentVersioning = "YES"
|
|
||||||
debugServiceExtension = "internal"
|
|
||||||
allowLocationSimulation = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAddressBook.framework"
|
|
||||||
BlueprintName = "PMKAddressBook"
|
|
||||||
ReferencedContainer = "container:PMKAddressBook.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
|
||||||
<ProfileAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
debugDocumentVersioning = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAddressBook.framework"
|
|
||||||
BlueprintName = "PMKAddressBook"
|
|
||||||
ReferencedContainer = "container:PMKAddressBook.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
</ProfileAction>
|
|
||||||
<AnalyzeAction
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
</AnalyzeAction>
|
|
||||||
<ArchiveAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
revealArchiveInOrganizer = "YES">
|
|
||||||
</ArchiveAction>
|
|
||||||
</Scheme>
|
|
@@ -1,34 +0,0 @@
|
|||||||
# PromiseKit AddressBook Extensions ![Build Status]
|
|
||||||
|
|
||||||
This project adds promises to Apple’s AddressBook framework.
|
|
||||||
|
|
||||||
## CococaPods
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
pod "PromiseKit/AddressBook" ~> 6.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into `PromiseKit.framework` thus nothing else is needed.
|
|
||||||
|
|
||||||
## Carthage
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
github "PromiseKit/AddressBook" ~> 3.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into their own framework:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// swift
|
|
||||||
import PromiseKit
|
|
||||||
import PMKAddressBook
|
|
||||||
```
|
|
||||||
|
|
||||||
```objc
|
|
||||||
// objc
|
|
||||||
@import PromiseKit;
|
|
||||||
@import PMKAddressBook;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
[Build Status]: https://travis-ci.org/PromiseKit/AddressBook.svg?branch=master
|
|
@@ -1,102 +0,0 @@
|
|||||||
import Foundation.NSError
|
|
||||||
import CoreFoundation
|
|
||||||
import AddressBook
|
|
||||||
#if !PMKCocoaPods
|
|
||||||
import PromiseKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public enum AddressBookError: Error {
|
|
||||||
case notDetermined
|
|
||||||
case restricted
|
|
||||||
case denied
|
|
||||||
|
|
||||||
public var localizedDescription: String {
|
|
||||||
switch self {
|
|
||||||
case .notDetermined:
|
|
||||||
return "Access to the address book could not be determined."
|
|
||||||
case .restricted:
|
|
||||||
return "A head of family must grant address book access."
|
|
||||||
case .denied:
|
|
||||||
return "Address book access has been denied."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Requests access to the address book.
|
|
||||||
|
|
||||||
To import `ABAddressBookRequestAccess`:
|
|
||||||
|
|
||||||
use_frameworks!
|
|
||||||
pod "PromiseKit/AddressBook"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
import PromiseKit
|
|
||||||
|
|
||||||
@return A promise that fulfills with the ABAuthorizationStatus.
|
|
||||||
*/
|
|
||||||
public func ABAddressBookRequestAccess() -> Promise<ABAuthorizationStatus> {
|
|
||||||
return ABAddressBookRequestAccess().map(on: nil) { (_, _) -> ABAuthorizationStatus in
|
|
||||||
return ABAddressBookGetAuthorizationStatus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Requests access to the address book.
|
|
||||||
|
|
||||||
To import `ABAddressBookRequestAccess`:
|
|
||||||
|
|
||||||
pod "PromiseKit/AddressBook"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
import PromiseKit
|
|
||||||
|
|
||||||
@return A promise that fulfills with the ABAddressBook instance if access was granted.
|
|
||||||
*/
|
|
||||||
public func ABAddressBookRequestAccess() -> Promise<ABAddressBook> {
|
|
||||||
return ABAddressBookRequestAccess().then(on: nil) { granted, book -> Promise<ABAddressBook> in
|
|
||||||
guard granted else {
|
|
||||||
switch ABAddressBookGetAuthorizationStatus() {
|
|
||||||
case .notDetermined:
|
|
||||||
throw AddressBookError.notDetermined
|
|
||||||
case .restricted:
|
|
||||||
throw AddressBookError.restricted
|
|
||||||
case .denied:
|
|
||||||
throw AddressBookError.denied
|
|
||||||
case .authorized:
|
|
||||||
fatalError("This should not happen")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return .value(book)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension NSError {
|
|
||||||
fileprivate convenience init(CFError error: CoreFoundation.CFError) {
|
|
||||||
let domain = CFErrorGetDomain(error) as String
|
|
||||||
let code = CFErrorGetCode(error)
|
|
||||||
let info = CFErrorCopyUserInfo(error) as? [String: Any] ?? [:]
|
|
||||||
self.init(domain: domain, code: code, userInfo: info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func ABAddressBookRequestAccess() -> Promise<(Bool, ABAddressBook)> {
|
|
||||||
var error: Unmanaged<CFError>? = nil
|
|
||||||
guard let ubook = ABAddressBookCreateWithOptions(nil, &error) else {
|
|
||||||
return Promise(error: NSError(CFError: error!.takeRetainedValue()))
|
|
||||||
}
|
|
||||||
|
|
||||||
let book: ABAddressBook = ubook.takeRetainedValue()
|
|
||||||
return Promise { seal in
|
|
||||||
ABAddressBookRequestAccessWithCompletion(book) { granted, error in
|
|
||||||
if let error = error {
|
|
||||||
seal.reject(NSError(CFError: error))
|
|
||||||
} else {
|
|
||||||
seal.fulfill((granted, book))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
import PMKAddressBook
|
|
||||||
import AddressBook
|
|
||||||
import PromiseKit
|
|
||||||
import XCTest
|
|
||||||
|
|
||||||
class AddressBookTests: XCTestCase {
|
|
||||||
func test() {
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
ABAddressBookRequestAccess().done { (auth: ABAuthorizationStatus) in
|
|
||||||
XCTAssertEqual(auth, ABAuthorizationStatus.authorized)
|
|
||||||
ex.fulfill()
|
|
||||||
}
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
*.xcodeproj/**/xcuserdata/
|
|
||||||
*.xcscmblueprint
|
|
||||||
/Carthage
|
|
||||||
/.build
|
|
||||||
.DS_Store
|
|
@@ -1,52 +0,0 @@
|
|||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- {osx_image: xcode8.3, env: 'PLAT=macOS SWFT=3.1 DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode8.3, env: 'PLAT=iOS SWFT=3.1 DST="OS=10.3.1,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode8.3, env: 'PLAT=tvOS SWFT=3.1 DST="OS=10.2,name=Apple TV 1080p"'}
|
|
||||||
- {osx_image: xcode8.3, env: 'PLAT=watchOS SWFT=3.1 DST="OS=3.2,name=Apple Watch - 38mm"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.3, env: 'PLAT=macOS SWFT=3.2 DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode9.3, env: 'PLAT=iOS SWFT=3.2 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.3, env: 'PLAT=tvOS SWFT=3.2 DST="OS=11.2,name=Apple TV"'}
|
|
||||||
- {osx_image: xcode9.3, env: 'PLAT=watchOS SWFT=3.2 DST="OS=4.2,name=Apple Watch - 38mm"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=macOS SWFT=3.3 DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=iOS SWFT=3.3 DST="OS=11.4,name=iPhone 5s"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=tvOS SWFT=3.3 DST="OS=11.4,name=Apple TV"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=watchOS SWFT=3.3 DST="OS=4.3,name=Apple Watch - 38mm"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=macOS SWFT=3.4 DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=iOS SWFT=3.4 DST="OS=11.4,name=iPhone 5s"'}
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=tvOS SWFT=3.4 DST="OS=11.4,name=Apple TV"'}
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=watchOS SWFT=3.4 DST="OS=5.0,name=Apple Watch Series 3 - 42mm"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.2, env: 'PLAT=macOS SWFT=4.0 DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=4.0 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'PLAT=tvOS SWFT=4.0 DST="OS=11.2,name=Apple TV"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'PLAT=watchOS SWFT=4.0 DST="OS=4.2,name=Apple Watch - 38mm"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=macOS SWFT=4.1 DST="arch=x86_64" TEST=1'}
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=iOS SWFT=4.1 DST="OS=11.4,name=iPhone 5s" TEST=1'}
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=tvOS SWFT=4.1 DST="OS=11.4,name=Apple TV" TEST=1'}
|
|
||||||
- {osx_image: xcode9.4, env: 'PLAT=watchOS SWFT=4.1 DST="OS=4.3,name=Apple Watch - 38mm"'}
|
|
||||||
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=macOS SWFT=4.2 DST="arch=x86_64"'}
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=iOS SWFT=4.2 DST="OS=11.4,name=iPhone 5s"'}
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=tvOS SWFT=4.2 DST="OS=11.4,name=Apple TV"'}
|
|
||||||
- {osx_image: xcode10, env: 'PLAT=watchOS SWFT=4.2 DST="OS=5.0,name=Apple Watch Series 3 - 42mm"'}
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- Carthage
|
|
||||||
before_install:
|
|
||||||
- carthage bootstrap --cache-builds --no-use-binaries --platform $PLAT --verbose
|
|
||||||
install:
|
|
||||||
- xcodebuild -scheme PMKAlamofire -target PMKAlamofire -quiet -destination "$DST" SWIFT_VERSION=$SWFT SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
- if [ "$TEST" == "1" ]; then
|
|
||||||
xcodebuild -scheme PMKAlamofire -target PMKAFTests -quiet -destination "$DST" build;
|
|
||||||
fi
|
|
||||||
script:
|
|
||||||
- if [ "$TEST" == "1" ]; then
|
|
||||||
xcodebuild -scheme PMKAlamofire -quiet -destination "$DST" test;
|
|
||||||
fi
|
|
@@ -1,2 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" ~> 6.0
|
|
||||||
github "Alamofire/Alamofire" ~> 4.0
|
|
@@ -1 +0,0 @@
|
|||||||
github "AliSoftware/OHHTTPStubs" ~> 6.0
|
|
@@ -1,3 +0,0 @@
|
|||||||
github "Alamofire/Alamofire" "4.7.2"
|
|
||||||
github "AliSoftware/OHHTTPStubs" "6.1.0"
|
|
||||||
github "mxcl/PromiseKit" "6.3.3"
|
|
@@ -1,7 +0,0 @@
|
|||||||
// Created by Kevin Ballard on 12/14/15.
|
|
||||||
// Copyright © 2015 Postmates. All rights reserved.
|
|
||||||
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SRCROOT)/Carthage/Build/Mac/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphone*] = $(SRCROOT)/Carthage/Build/iOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=watch*] = $(SRCROOT)/Carthage/Build/watchOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=appletv*] = $(SRCROOT)/Carthage/Build/tvOS/ $(inherited)
|
|
@@ -1,24 +0,0 @@
|
|||||||
<?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>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>FMWK</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
||||||
<key>NSPrincipalClass</key>
|
|
||||||
<string></string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,451 +0,0 @@
|
|||||||
// !$*UTF8*$!
|
|
||||||
{
|
|
||||||
archiveVersion = 1;
|
|
||||||
classes = {
|
|
||||||
};
|
|
||||||
objectVersion = 46;
|
|
||||||
objects = {
|
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
|
||||||
63C700081D5C021F003BAE60 /* TestAlamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C700021D5C021F003BAE60 /* TestAlamofire.swift */; };
|
|
||||||
63C7FFE91D5C00F2003BAE60 /* Alamofire+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C7FFDB1D5C00F2003BAE60 /* Alamofire+Promise.swift */; };
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAlamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKAlamofire.framework */; };
|
|
||||||
/* End PBXBuildFile section */
|
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
|
||||||
63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 63C7FFA61D5BEE09003BAE60;
|
|
||||||
remoteInfo = PMKFoundation;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
|
||||||
63C700021D5C021F003BAE60 /* TestAlamofire.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestAlamofire.swift; path = Tests/TestAlamofire.swift; sourceTree = SOURCE_ROOT; };
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAlamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PMKAlamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63C7FFDB1D5C00F2003BAE60 /* Alamofire+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Alamofire+Promise.swift"; path = "Sources/Alamofire+Promise.swift"; sourceTree = SOURCE_ROOT; };
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKAFTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKAFTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63CCF8121D5C0C4E00503216 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
|
|
||||||
63CCF8131D5C0C4E00503216 /* Cartfile.private */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile.private; sourceTree = "<group>"; };
|
|
||||||
63CCF8171D5C11B500503216 /* Carthage.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Carthage.xcconfig; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
|
||||||
63C7FFA31D5BEE09003BAE60 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63C7FFF71D5C020D003BAE60 /* PMKAlamofire.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
|
||||||
63C7FF9D1D5BEE09003BAE60 = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */,
|
|
||||||
63CCF8121D5C0C4E00503216 /* Cartfile */,
|
|
||||||
63CCF8131D5C0C4E00503216 /* Cartfile.private */,
|
|
||||||
63CCF8171D5C11B500503216 /* Carthage.xcconfig */,
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */,
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */,
|
|
||||||
);
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAlamofire.framework */,
|
|
||||||
63C7FFF21D5C020D003BAE60 /* PMKAFTests.xctest */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C7FFDB1D5C00F2003BAE60 /* Alamofire+Promise.swift */,
|
|
||||||
);
|
|
||||||
path = Sources;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C700021D5C021F003BAE60 /* TestAlamofire.swift */,
|
|
||||||
);
|
|
||||||
path = Tests;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */ = {
|
|
||||||
isa = PBXHeadersBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXHeadersBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAlamofire */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAlamofire" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFA31D5BEE09003BAE60 /* Frameworks */,
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = PMKAlamofire;
|
|
||||||
productName = "PMK+UIKit";
|
|
||||||
productReference = 63C7FFA71D5BEE09003BAE60 /* PMKAlamofire.framework */;
|
|
||||||
productType = "com.apple.product-type.framework";
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKAFTests */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKAFTests" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */,
|
|
||||||
63C7FFEF1D5C020D003BAE60 /* Frameworks */,
|
|
||||||
639447051D5D011300DDAE3C /* Embed Carthage Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = PMKAFTests;
|
|
||||||
productName = PMKTests/NS;
|
|
||||||
productReference = 63C7FFF21D5C020D003BAE60 /* PMKAFTests.xctest */;
|
|
||||||
productType = "com.apple.product-type.bundle.unit-test";
|
|
||||||
};
|
|
||||||
/* End PBXNativeTarget section */
|
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
|
||||||
63C7FF9E1D5BEE09003BAE60 /* Project object */ = {
|
|
||||||
isa = PBXProject;
|
|
||||||
attributes = {
|
|
||||||
LastSwiftUpdateCheck = 0800;
|
|
||||||
LastUpgradeCheck = 0930;
|
|
||||||
ORGANIZATIONNAME = "Max Howell";
|
|
||||||
TargetAttributes = {
|
|
||||||
63C7FFA61D5BEE09003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
63C7FFF11D5C020D003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildConfigurationList = 63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAlamofire" */;
|
|
||||||
compatibilityVersion = "Xcode 3.2";
|
|
||||||
developmentRegion = English;
|
|
||||||
hasScannedForEncodings = 0;
|
|
||||||
knownRegions = (
|
|
||||||
en,
|
|
||||||
);
|
|
||||||
mainGroup = 63C7FF9D1D5BEE09003BAE60;
|
|
||||||
productRefGroup = 63C7FFA81D5BEE09003BAE60 /* Products */;
|
|
||||||
projectDirPath = "";
|
|
||||||
projectRoot = "";
|
|
||||||
targets = (
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAlamofire */,
|
|
||||||
63C7FFF11D5C020D003BAE60 /* PMKAFTests */,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
/* End PBXProject section */
|
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
639447051D5D011300DDAE3C /* Embed Carthage Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
PromiseKit,
|
|
||||||
OHHTTPStubs,
|
|
||||||
Alamofire,
|
|
||||||
);
|
|
||||||
name = "Embed Carthage Frameworks";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "case \"$PLATFORM_NAME\" in\nmacosx) plat=Mac;;\niphone*) plat=iOS;;\nwatch*) plat=watchOS;;\nappletv*) plat=tvOS;;\n*) echo \"error: Unknown PLATFORM_NAME: $PLATFORM_NAME\"; exit 1;;\nesac\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nframework=$(basename \"${!VAR}\")\nexport SCRIPT_INPUT_FILE_$n=\"$SRCROOT\"/Carthage/Build/$plat/\"$framework\".framework\ndone\n\n/usr/local/bin/carthage copy-frameworks || exit\n\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nsource=${!VAR}.dSYM\ndest=${BUILT_PRODUCTS_DIR}/$(basename \"$source\")\nditto \"$source\" \"$dest\" || exit\ndone";
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63C7FFE91D5C00F2003BAE60 /* Alamofire+Promise.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C7FFEE1D5C020D003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63C700081D5C021F003BAE60 /* TestAlamofire.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
|
||||||
63C7FFF91D5C020D003BAE60 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 63C7FFA61D5BEE09003BAE60 /* PMKAlamofire */;
|
|
||||||
targetProxy = 63C7FFF81D5C020D003BAE60 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63CCF8171D5C11B500503216 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1.0.6;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
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",
|
|
||||||
"$(inherited)",
|
|
||||||
);
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchsimulator watchos macosx appletvsimulator appletvos";
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63CCF8171D5C11B500503216 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1.0.6;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
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;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.Foundation;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchsimulator watchos macosx appletvsimulator appletvos";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
|
||||||
63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAlamofire" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAlamofire" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFFA1D5C020D003BAE60 /* Build configuration list for PBXNativeTarget "PMKAFTests" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFFB1D5C020D003BAE60 /* Debug */,
|
|
||||||
63C7FFFC1D5C020D003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
|
||||||
};
|
|
||||||
rootObject = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "self:/Users/mxcl/PMKX/Alamofire/PMKAlamofire.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,107 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Scheme
|
|
||||||
LastUpgradeVersion = "0930"
|
|
||||||
version = "1.3">
|
|
||||||
<BuildAction
|
|
||||||
parallelizeBuildables = "YES"
|
|
||||||
buildImplicitDependencies = "NO">
|
|
||||||
<BuildActionEntries>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "NO"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAlamofire.framework"
|
|
||||||
BlueprintName = "PMKAlamofire"
|
|
||||||
ReferencedContainer = "container:PMKAlamofire.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
||||||
<Testables>
|
|
||||||
<TestableReference
|
|
||||||
skipped = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFF11D5C020D003BAE60"
|
|
||||||
BuildableName = "PMKAFTests.xctest"
|
|
||||||
BlueprintName = "PMKAFTests"
|
|
||||||
ReferencedContainer = "container:PMKAlamofire.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
<SkippedTests>
|
|
||||||
<Test
|
|
||||||
Identifier = "NSURLSessionTests/test200">
|
|
||||||
</Test>
|
|
||||||
<Test
|
|
||||||
Identifier = "NSURLSessionTests/testBadJSON">
|
|
||||||
</Test>
|
|
||||||
</SkippedTests>
|
|
||||||
</TestableReference>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAlamofire.framework"
|
|
||||||
BlueprintName = "PMKAlamofire"
|
|
||||||
ReferencedContainer = "container:PMKAlamofire.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
|
||||||
<LaunchAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
launchStyle = "0"
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
|
||||||
debugDocumentVersioning = "YES"
|
|
||||||
debugServiceExtension = "internal"
|
|
||||||
allowLocationSimulation = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAlamofire.framework"
|
|
||||||
BlueprintName = "PMKAlamofire"
|
|
||||||
ReferencedContainer = "container:PMKAlamofire.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
|
||||||
<ProfileAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
debugDocumentVersioning = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAlamofire.framework"
|
|
||||||
BlueprintName = "PMKAlamofire"
|
|
||||||
ReferencedContainer = "container:PMKAlamofire.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
</ProfileAction>
|
|
||||||
<AnalyzeAction
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
</AnalyzeAction>
|
|
||||||
<ArchiveAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
revealArchiveInOrganizer = "YES">
|
|
||||||
</ArchiveAction>
|
|
||||||
</Scheme>
|
|
@@ -1,10 +0,0 @@
|
|||||||
import PackageDescription
|
|
||||||
|
|
||||||
let package = Package(
|
|
||||||
name: "PMKAlamofire",
|
|
||||||
dependencies: [
|
|
||||||
.Package(url: "https://github.com/mxcl/PromiseKit.git", majorVersion: 4),
|
|
||||||
.Package(url: "https://github.com/Alamofire/Alamofire.git", majorVersion: 4)
|
|
||||||
],
|
|
||||||
exclude: ["Tests"]
|
|
||||||
)
|
|
@@ -1,93 +0,0 @@
|
|||||||
# PromiseKit Alamofire Extensions ![Build Status]
|
|
||||||
|
|
||||||
This project adds promises to [Alamofire](https://github.com/Alamofire/Alamofire).
|
|
||||||
|
|
||||||
This project supports Swift 3.1, 3.2, 4.0 and 4.1.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```swift
|
|
||||||
Alamofire.request("https://httpbin.org/get", method: .GET)
|
|
||||||
.responseJSON().then { json, rsp in
|
|
||||||
//
|
|
||||||
}.catch{ error in
|
|
||||||
//…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Of course, the whole point in promises is composability, so:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
func login() -> Promise<User> {
|
|
||||||
let q = DispatchQueue.global()
|
|
||||||
UIApplication.shared.isNetworkActivityIndicatorVisible = true
|
|
||||||
|
|
||||||
return firstly { in
|
|
||||||
Alamofire.request(url, method: .get).responseData()
|
|
||||||
}.map(on: q) { data, rsp in
|
|
||||||
convertToUser(data)
|
|
||||||
}.ensure {
|
|
||||||
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
firstly {
|
|
||||||
login()
|
|
||||||
}.done { user in
|
|
||||||
//…
|
|
||||||
}.catch { error in
|
|
||||||
UIAlertController(/*…*/).show()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## CococaPods
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
# Podfile
|
|
||||||
pod 'PromiseKit/Alamofire', '~> 6.0'
|
|
||||||
```
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// `.swift` files
|
|
||||||
import PromiseKit
|
|
||||||
import Alamofire
|
|
||||||
```
|
|
||||||
|
|
||||||
```objc
|
|
||||||
// `.m files`
|
|
||||||
@import PromiseKit;
|
|
||||||
@import Alamofire;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Carthage
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
github "PromiseKit/Alamofire-" ~> 3.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into their own framework:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// `.swift` files
|
|
||||||
import PromiseKit
|
|
||||||
import PMKAlamofire
|
|
||||||
```
|
|
||||||
|
|
||||||
```objc
|
|
||||||
// `.m files`
|
|
||||||
@import PromiseKit;
|
|
||||||
@import PMKAlamofire;
|
|
||||||
```
|
|
||||||
|
|
||||||
## SwiftPM
|
|
||||||
|
|
||||||
```swift
|
|
||||||
let package = Package(
|
|
||||||
dependencies: [
|
|
||||||
.Target(url: "https://github.com/PromiseKit/Alamofire", majorVersion: 3)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
[Build Status]: https://travis-ci.org/PromiseKit/Alamofire.svg?branch=master
|
|
@@ -1,189 +0,0 @@
|
|||||||
@_exported import Alamofire
|
|
||||||
import Foundation
|
|
||||||
#if !PMKCocoaPods
|
|
||||||
import PromiseKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
To import the `Alamofire` category:
|
|
||||||
|
|
||||||
use_frameworks!
|
|
||||||
pod "PromiseKit/Alamofire"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
import PromiseKit
|
|
||||||
*/
|
|
||||||
extension Alamofire.DataRequest {
|
|
||||||
/// Adds a handler to be called once the request has finished.
|
|
||||||
public func response(_: PMKNamespacer, queue: DispatchQueue? = nil) -> Promise<(URLRequest, HTTPURLResponse, Data)> {
|
|
||||||
return Promise { seal in
|
|
||||||
response(queue: queue) { rsp in
|
|
||||||
if let error = rsp.error {
|
|
||||||
seal.reject(error)
|
|
||||||
} else if let a = rsp.request, let b = rsp.response, let c = rsp.data {
|
|
||||||
seal.fulfill((a, b, c))
|
|
||||||
} else {
|
|
||||||
seal.reject(PMKError.invalidCallingConvention)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a handler to be called once the request has finished.
|
|
||||||
public func responseData(queue: DispatchQueue? = nil) -> Promise<(data: Data, response: PMKAlamofireDataResponse)> {
|
|
||||||
return Promise { seal in
|
|
||||||
responseData(queue: queue) { response in
|
|
||||||
switch response.result {
|
|
||||||
case .success(let value):
|
|
||||||
seal.fulfill((value, PMKAlamofireDataResponse(response)))
|
|
||||||
case .failure(let error):
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a handler to be called once the request has finished.
|
|
||||||
public func responseString(queue: DispatchQueue? = nil) -> Promise<(string: String, response: PMKAlamofireDataResponse)> {
|
|
||||||
return Promise { seal in
|
|
||||||
responseString(queue: queue) { response in
|
|
||||||
switch response.result {
|
|
||||||
case .success(let value):
|
|
||||||
seal.fulfill((value, PMKAlamofireDataResponse(response)))
|
|
||||||
case .failure(let error):
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a handler to be called once the request has finished.
|
|
||||||
public func responseJSON(queue: DispatchQueue? = nil, options: JSONSerialization.ReadingOptions = .allowFragments) -> Promise<(json: Any, response: PMKAlamofireDataResponse)> {
|
|
||||||
return Promise { seal in
|
|
||||||
responseJSON(queue: queue, options: options) { response in
|
|
||||||
switch response.result {
|
|
||||||
case .success(let value):
|
|
||||||
seal.fulfill((value, PMKAlamofireDataResponse(response)))
|
|
||||||
case .failure(let error):
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a handler to be called once the request has finished.
|
|
||||||
public func responsePropertyList(queue: DispatchQueue? = nil, options: PropertyListSerialization.ReadOptions = PropertyListSerialization.ReadOptions()) -> Promise<(plist: Any, response: PMKAlamofireDataResponse)> {
|
|
||||||
return Promise { seal in
|
|
||||||
responsePropertyList(queue: queue, options: options) { response in
|
|
||||||
switch response.result {
|
|
||||||
case .success(let value):
|
|
||||||
seal.fulfill((value, PMKAlamofireDataResponse(response)))
|
|
||||||
case .failure(let error):
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if swift(>=3.2)
|
|
||||||
/**
|
|
||||||
Returns a Promise for a Decodable
|
|
||||||
Adds a handler to be called once the request has finished.
|
|
||||||
|
|
||||||
- Parameter queue: DispatchQueue, by default nil
|
|
||||||
- Parameter decoder: JSONDecoder, by default JSONDecoder()
|
|
||||||
*/
|
|
||||||
public func responseDecodable<T: Decodable>(queue: DispatchQueue? = nil, decoder: JSONDecoder = JSONDecoder()) -> Promise<T> {
|
|
||||||
return Promise { seal in
|
|
||||||
responseData(queue: queue) { response in
|
|
||||||
switch response.result {
|
|
||||||
case .success(let value):
|
|
||||||
do {
|
|
||||||
seal.fulfill(try decoder.decode(T.self, from: value))
|
|
||||||
} catch {
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns a Promise for a Decodable
|
|
||||||
Adds a handler to be called once the request has finished.
|
|
||||||
|
|
||||||
- Parameter queue: DispatchQueue, by default nil
|
|
||||||
- Parameter decoder: JSONDecoder, by default JSONDecoder()
|
|
||||||
*/
|
|
||||||
public func responseDecodable<T: Decodable>(_ type: T.Type, queue: DispatchQueue? = nil, decoder: JSONDecoder = JSONDecoder()) -> Promise<T> {
|
|
||||||
return Promise { seal in
|
|
||||||
responseData(queue: queue) { response in
|
|
||||||
switch response.result {
|
|
||||||
case .success(let value):
|
|
||||||
do {
|
|
||||||
seal.fulfill(try decoder.decode(type, from: value))
|
|
||||||
} catch {
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Alamofire.DownloadRequest {
|
|
||||||
public func response(_: PMKNamespacer, queue: DispatchQueue? = nil) -> Promise<DefaultDownloadResponse> {
|
|
||||||
return Promise { seal in
|
|
||||||
response(queue: queue) { response in
|
|
||||||
if let error = response.error {
|
|
||||||
seal.reject(error)
|
|
||||||
} else {
|
|
||||||
seal.fulfill(response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a handler to be called once the request has finished.
|
|
||||||
public func responseData(queue: DispatchQueue? = nil) -> Promise<DownloadResponse<Data>> {
|
|
||||||
return Promise { seal in
|
|
||||||
responseData(queue: queue) { response in
|
|
||||||
switch response.result {
|
|
||||||
case .success:
|
|
||||||
seal.fulfill(response)
|
|
||||||
case .failure(let error):
|
|
||||||
seal.reject(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Alamofire.DataResponse, but without the `result`, since the Promise represents the `Result`
|
|
||||||
public struct PMKAlamofireDataResponse {
|
|
||||||
public init<T>(_ rawrsp: Alamofire.DataResponse<T>) {
|
|
||||||
request = rawrsp.request
|
|
||||||
response = rawrsp.response
|
|
||||||
data = rawrsp.data
|
|
||||||
timeline = rawrsp.timeline
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The URL request sent to the server.
|
|
||||||
public let request: URLRequest?
|
|
||||||
|
|
||||||
/// The server's response to the URL request.
|
|
||||||
public let response: HTTPURLResponse?
|
|
||||||
|
|
||||||
/// The data returned by the server.
|
|
||||||
public let data: Data?
|
|
||||||
|
|
||||||
/// The timeline of the complete lifecycle of the request.
|
|
||||||
public let timeline: Timeline
|
|
||||||
}
|
|
@@ -1,74 +0,0 @@
|
|||||||
import PMKAlamofire
|
|
||||||
import OHHTTPStubs
|
|
||||||
import PromiseKit
|
|
||||||
import XCTest
|
|
||||||
|
|
||||||
class AlamofireTests: XCTestCase {
|
|
||||||
func test() {
|
|
||||||
let json: NSDictionary = ["key1": "value1", "key2": ["value2A", "value2B"]]
|
|
||||||
|
|
||||||
OHHTTPStubs.stubRequests(passingTest: { $0.url!.host == "example.com" }) { _ in
|
|
||||||
return OHHTTPStubsResponse(jsonObject: json, statusCode: 200, headers: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
|
|
||||||
let rq = Alamofire.request("http://example.com", method: .get).responseJSON().done { rsp in
|
|
||||||
XCTAssertEqual(json, rsp.json as? NSDictionary)
|
|
||||||
ex.fulfill()
|
|
||||||
}
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tearDown() {
|
|
||||||
OHHTTPStubs.removeAllStubs()
|
|
||||||
}
|
|
||||||
|
|
||||||
#if swift(>=3.2)
|
|
||||||
private struct Fixture: Decodable {
|
|
||||||
let key1: String
|
|
||||||
let key2: [String]
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDecodable1() {
|
|
||||||
|
|
||||||
func getFixture() -> Promise<Fixture> {
|
|
||||||
return Alamofire.request("http://example.com", method: .get).responseDecodable(queue: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
let json: NSDictionary = ["key1": "value1", "key2": ["value2A", "value2B"]]
|
|
||||||
|
|
||||||
OHHTTPStubs.stubRequests(passingTest: { $0.url!.host == "example.com" }) { _ in
|
|
||||||
return OHHTTPStubsResponse(jsonObject: json, statusCode: 200, headers: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
|
|
||||||
getFixture().done { fixture in
|
|
||||||
XCTAssert(fixture.key1 == "value1", "Value1 found")
|
|
||||||
ex.fulfill()
|
|
||||||
}
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDecodable2() {
|
|
||||||
let json: NSDictionary = ["key1": "value1", "key2": ["value2A", "value2B"]]
|
|
||||||
|
|
||||||
OHHTTPStubs.stubRequests(passingTest: { $0.url!.host == "example.com" }) { _ in
|
|
||||||
return OHHTTPStubsResponse(jsonObject: json, statusCode: 200, headers: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
let ex = expectation(description: "")
|
|
||||||
|
|
||||||
firstly {
|
|
||||||
Alamofire.request("http://example.com", method: .get).responseDecodable(Fixture.self)
|
|
||||||
}.done { fixture in
|
|
||||||
XCTAssert(fixture.key1 == "value1", "Value1 found")
|
|
||||||
ex.fulfill()
|
|
||||||
}
|
|
||||||
waitForExpectations(timeout: 1)
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
*.xcodeproj/**/xcuserdata/
|
|
||||||
*.xcscmblueprint
|
|
||||||
/Carthage
|
|
||||||
/.build
|
|
||||||
.DS_Store
|
|
@@ -1,25 +0,0 @@
|
|||||||
os: osx
|
|
||||||
language: objective-c
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- {osx_image: xcode8.3, env: 'SWFT=3.1 DST="OS=10.3.1,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=3.2 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=3.3 DST="OS=11.4,name=iPhone 5s"'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=3.4 DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.2, env: 'SWFT=4.0 DST="OS=11.2,name=iPhone SE"'}
|
|
||||||
- {osx_image: xcode9.4, env: 'SWFT=4.1 DST="OS=11.4,name=iPhone 5s" TEST=1'}
|
|
||||||
- {osx_image: xcode10, env: 'SWFT=4.2 DST="OS=12.0,name=iPhone SE"'}
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- Carthage
|
|
||||||
before_install:
|
|
||||||
- carthage bootstrap --cache-builds --no-use-binaries --platform iOS --verbose
|
|
||||||
install:
|
|
||||||
- xcodebuild -scheme PMKAssetsLibrary -target PMKAssetsLibrary -quiet -destination "$DST" SWIFT_VERSION=$SWFT SWIFT_TREAT_WARNINGS_AS_ERRORS=YES build
|
|
||||||
- if [[ $TEST == "1" ]]; then
|
|
||||||
xcodebuild -scheme PMKAssetsLibrary -target PMKALTests -quiet -destination "$DST" build;
|
|
||||||
fi
|
|
||||||
script:
|
|
||||||
- if [ "$TEST" == "1" ]; then
|
|
||||||
xcodebuild -scheme PMKAssetsLibrary -quiet -destination "$DST" test;
|
|
||||||
fi
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" ~> 6.0
|
|
@@ -1 +0,0 @@
|
|||||||
github "mxcl/PromiseKit" "6.3.4"
|
|
@@ -1,7 +0,0 @@
|
|||||||
// Created by Kevin Ballard on 12/14/15.
|
|
||||||
// Copyright © 2015 Postmates. All rights reserved.
|
|
||||||
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SRCROOT)/Carthage/Build/Mac/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphone*] = $(SRCROOT)/Carthage/Build/iOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=watch*] = $(SRCROOT)/Carthage/Build/watchOS/ $(inherited)
|
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=appletv*] = $(SRCROOT)/Carthage/Build/tvOS/ $(inherited)
|
|
@@ -1,24 +0,0 @@
|
|||||||
<?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>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>$(BUNDLE_PACKAGE_TYPE)</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
||||||
<key>NSPrincipalClass</key>
|
|
||||||
<string></string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,599 +0,0 @@
|
|||||||
// !$*UTF8*$!
|
|
||||||
{
|
|
||||||
archiveVersion = 1;
|
|
||||||
classes = {
|
|
||||||
};
|
|
||||||
objectVersion = 46;
|
|
||||||
objects = {
|
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
|
||||||
6362F8521D5DA15A0021D2DD /* app.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6362F8501D5DA15A0021D2DD /* app.swift */; };
|
|
||||||
6362F8531D5DA15A0021D2DD /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6362F8511D5DA15A0021D2DD /* Default-568h@2x.png */; };
|
|
||||||
6362F8541D5DA16A0021D2DD /* TestUIImagePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637E2C8E1D5C2E720043E370 /* TestUIImagePickerController.swift */; };
|
|
||||||
6362F8561D5DA1750021D2DD /* ALAssetsLibrary+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6362F8551D5DA1750021D2DD /* ALAssetsLibrary+Promise.swift */; };
|
|
||||||
63C9C45E1D5D341600101ECE /* PMKAssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKAssetsLibrary.framework */; };
|
|
||||||
63C9C45F1D5D341600101ECE /* PMKAssetsLibrary.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKAssetsLibrary.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
|
||||||
/* End PBXBuildFile section */
|
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
|
||||||
63C9C4591D5D33A900101ECE /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 63C9C4441D5D334700101ECE;
|
|
||||||
remoteInfo = PMKTestsHost;
|
|
||||||
};
|
|
||||||
63C9C4601D5D341600101ECE /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 63C7FFA61D5BEE09003BAE60;
|
|
||||||
remoteInfo = PMKAssetsLibrary;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
|
||||||
63C9C4621D5D341600101ECE /* Embed Frameworks */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 10;
|
|
||||||
files = (
|
|
||||||
63C9C45F1D5D341600101ECE /* PMKAssetsLibrary.framework in Embed Frameworks */,
|
|
||||||
);
|
|
||||||
name = "Embed Frameworks";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
|
||||||
630B2E131D5D0AF500DC10E9 /* PMKALTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKALTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
6362F8501D5DA15A0021D2DD /* app.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = app.swift; path = Tests/app.swift; sourceTree = "<group>"; };
|
|
||||||
6362F8511D5DA15A0021D2DD /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "Tests/Default-568h@2x.png"; sourceTree = "<group>"; };
|
|
||||||
6362F8551D5DA1750021D2DD /* ALAssetsLibrary+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "ALAssetsLibrary+Promise.swift"; path = "Sources/ALAssetsLibrary+Promise.swift"; sourceTree = SOURCE_ROOT; };
|
|
||||||
637E2C8E1D5C2E720043E370 /* TestUIImagePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestUIImagePickerController.swift; path = Tests/TestUIImagePickerController.swift; sourceTree = SOURCE_ROOT; };
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAssetsLibrary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PMKAssetsLibrary.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63C9C4451D5D334700101ECE /* PMKALTestsHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PMKALTestsHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
63CCF8121D5C0C4E00503216 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
|
|
||||||
63CCF8171D5C11B500503216 /* Carthage.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Carthage.xcconfig; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
|
||||||
630B2E0D1D5D0AF500DC10E9 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C7FFA31D5BEE09003BAE60 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C9C4421D5D334700101ECE /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
63C9C45E1D5D341600101ECE /* PMKAssetsLibrary.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
|
||||||
630B2DF31D5D0ABF00DC10E9 /* TestsHost */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
6362F8501D5DA15A0021D2DD /* app.swift */,
|
|
||||||
6362F8511D5DA15A0021D2DD /* Default-568h@2x.png */,
|
|
||||||
);
|
|
||||||
name = TestsHost;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FF9D1D5BEE09003BAE60 = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C700091D5C0253003BAE60 /* Info.plist */,
|
|
||||||
63CCF8121D5C0C4E00503216 /* Cartfile */,
|
|
||||||
63CCF8171D5C11B500503216 /* Carthage.xcconfig */,
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */,
|
|
||||||
630B2DF31D5D0ABF00DC10E9 /* TestsHost */,
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */,
|
|
||||||
);
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA81D5BEE09003BAE60 /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
63C7FFA71D5BEE09003BAE60 /* PMKAssetsLibrary.framework */,
|
|
||||||
630B2E131D5D0AF500DC10E9 /* PMKALTests.xctest */,
|
|
||||||
63C9C4451D5D334700101ECE /* PMKALTestsHost.app */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
63C7FFA91D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
6362F8551D5DA1750021D2DD /* ALAssetsLibrary+Promise.swift */,
|
|
||||||
);
|
|
||||||
path = Sources;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
63C7FFF31D5C020D003BAE60 /* Tests */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
637E2C8E1D5C2E720043E370 /* TestUIImagePickerController.swift */,
|
|
||||||
);
|
|
||||||
path = Tests;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */ = {
|
|
||||||
isa = PBXHeadersBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXHeadersBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
|
||||||
630B2DFF1D5D0AF500DC10E9 /* PMKALTests */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 630B2E101D5D0AF500DC10E9 /* Build configuration list for PBXNativeTarget "PMKALTests" */;
|
|
||||||
buildPhases = (
|
|
||||||
630B2E041D5D0AF500DC10E9 /* Sources */,
|
|
||||||
630B2E0D1D5D0AF500DC10E9 /* Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
63C9C45A1D5D33A900101ECE /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = PMKALTests;
|
|
||||||
productName = PMKALTests;
|
|
||||||
productReference = 630B2E131D5D0AF500DC10E9 /* PMKALTests.xctest */;
|
|
||||||
productType = "com.apple.product-type.bundle.ui-testing";
|
|
||||||
};
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAssetsLibrary */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAssetsLibrary" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */,
|
|
||||||
63C7FFA31D5BEE09003BAE60 /* Frameworks */,
|
|
||||||
63C7FFA41D5BEE09003BAE60 /* Headers */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = PMKAssetsLibrary;
|
|
||||||
productName = PMKAssetsLibrary;
|
|
||||||
productReference = 63C7FFA71D5BEE09003BAE60 /* PMKAssetsLibrary.framework */;
|
|
||||||
productType = "com.apple.product-type.framework";
|
|
||||||
};
|
|
||||||
63C9C4441D5D334700101ECE /* PMKALTestsHost */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = 63C9C4541D5D334800101ECE /* Build configuration list for PBXNativeTarget "PMKALTestsHost" */;
|
|
||||||
buildPhases = (
|
|
||||||
63C9C4411D5D334700101ECE /* Sources */,
|
|
||||||
63C9C4421D5D334700101ECE /* Frameworks */,
|
|
||||||
63C9C4431D5D334700101ECE /* Resources */,
|
|
||||||
63C9C45D1D5D33E700101ECE /* Embed Carthage Frameworks */,
|
|
||||||
63C9C4621D5D341600101ECE /* Embed Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
63C9C4611D5D341600101ECE /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = PMKALTestsHost;
|
|
||||||
productName = PMKTestsHost;
|
|
||||||
productReference = 63C9C4451D5D334700101ECE /* PMKALTestsHost.app */;
|
|
||||||
productType = "com.apple.product-type.application";
|
|
||||||
};
|
|
||||||
/* End PBXNativeTarget section */
|
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
|
||||||
63C7FF9E1D5BEE09003BAE60 /* Project object */ = {
|
|
||||||
isa = PBXProject;
|
|
||||||
attributes = {
|
|
||||||
LastSwiftUpdateCheck = 0800;
|
|
||||||
LastUpgradeCheck = 1000;
|
|
||||||
ORGANIZATIONNAME = "Max Howell";
|
|
||||||
TargetAttributes = {
|
|
||||||
630B2DFF1D5D0AF500DC10E9 = {
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
TestTargetID = 63C9C4441D5D334700101ECE;
|
|
||||||
};
|
|
||||||
63C7FFA61D5BEE09003BAE60 = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
63C9C4441D5D334700101ECE = {
|
|
||||||
CreatedOnToolsVersion = 8.0;
|
|
||||||
LastSwiftMigration = 0900;
|
|
||||||
ProvisioningStyle = Automatic;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildConfigurationList = 63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAssetsLibrary" */;
|
|
||||||
compatibilityVersion = "Xcode 3.2";
|
|
||||||
developmentRegion = English;
|
|
||||||
hasScannedForEncodings = 0;
|
|
||||||
knownRegions = (
|
|
||||||
en,
|
|
||||||
Base,
|
|
||||||
);
|
|
||||||
mainGroup = 63C7FF9D1D5BEE09003BAE60;
|
|
||||||
productRefGroup = 63C7FFA81D5BEE09003BAE60 /* Products */;
|
|
||||||
projectDirPath = "";
|
|
||||||
projectRoot = "";
|
|
||||||
targets = (
|
|
||||||
63C7FFA61D5BEE09003BAE60 /* PMKAssetsLibrary */,
|
|
||||||
63C9C4441D5D334700101ECE /* PMKALTestsHost */,
|
|
||||||
630B2DFF1D5D0AF500DC10E9 /* PMKALTests */,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
/* End PBXProject section */
|
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
|
||||||
63C9C4431D5D334700101ECE /* Resources */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
6362F8531D5DA15A0021D2DD /* Default-568h@2x.png in Resources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXResourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
63C9C45D1D5D33E700101ECE /* Embed Carthage Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
PromiseKit,
|
|
||||||
);
|
|
||||||
name = "Embed Carthage Frameworks";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "case \"$PLATFORM_NAME\" in\nmacosx) plat=Mac;;\niphone*) plat=iOS;;\nwatch*) plat=watchOS;;\nappletv*) plat=tvOS;;\n*) echo \"error: Unknown PLATFORM_NAME: $PLATFORM_NAME\"; exit 1;;\nesac\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nframework=$(basename \"${!VAR}\")\nexport SCRIPT_INPUT_FILE_$n=\"$SRCROOT\"/Carthage/Build/$plat/\"$framework\".framework\ndone\n\n/usr/local/bin/carthage copy-frameworks || exit\n\nfor (( n = 0; n < SCRIPT_INPUT_FILE_COUNT; n++ )); do\nVAR=SCRIPT_INPUT_FILE_$n\nsource=${!VAR}.dSYM\ndest=${BUILT_PRODUCTS_DIR}/$(basename \"$source\")\nditto \"$source\" \"$dest\" || exit\ndone";
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
|
||||||
630B2E041D5D0AF500DC10E9 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
6362F8541D5DA16A0021D2DD /* TestUIImagePickerController.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C7FFA21D5BEE09003BAE60 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
6362F8561D5DA1750021D2DD /* ALAssetsLibrary+Promise.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
63C9C4411D5D334700101ECE /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
6362F8521D5DA15A0021D2DD /* app.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
|
||||||
63C9C45A1D5D33A900101ECE /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 63C9C4441D5D334700101ECE /* PMKALTestsHost */;
|
|
||||||
targetProxy = 63C9C4591D5D33A900101ECE /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
63C9C4611D5D341600101ECE /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 63C7FFA61D5BEE09003BAE60 /* PMKAssetsLibrary */;
|
|
||||||
targetProxy = 63C9C4601D5D341600101ECE /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
|
||||||
630B2E111D5D0AF500DC10E9 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
BUNDLE_PACKAGE_TYPE = BNDL;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.tests.ui.UIKit;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
PROVISIONING_PROFILE = "";
|
|
||||||
SWIFT_INSTALL_OBJC_HEADER = NO;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
TEST_TARGET_NAME = PMKALTestsHost;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
630B2E121D5D0AF500DC10E9 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
BUNDLE_PACKAGE_TYPE = BNDL;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
GCC_WARN_INHIBIT_ALL_WARNINGS = YES;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.tests.ui.UIKit;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
PROVISIONING_PROFILE = "";
|
|
||||||
SWIFT_INSTALL_OBJC_HEADER = NO;
|
|
||||||
SWIFT_SUPPRESS_WARNINGS = YES;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
TEST_TARGET_NAME = PMKALTestsHost;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63CCF8171D5C11B500503216 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
BUNDLE_PACKAGE_TYPE = FMWK;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
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",
|
|
||||||
"$(inherited)",
|
|
||||||
);
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.UIKit;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 63CCF8171D5C11B500503216 /* Carthage.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
BUNDLE_PACKAGE_TYPE = FMWK;
|
|
||||||
CLANG_ANALYZER_NONNULL = 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_DOCUMENTATION_COMMENTS = YES;
|
|
||||||
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_SUSPICIOUS_MOVES = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
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;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.UIKit;
|
|
||||||
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
|
||||||
PRODUCT_MODULE_NAME = "${TARGET_NAME}";
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
63C9C4551D5D334800101ECE /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
BUNDLE_PACKAGE_TYPE = APPL;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = Tests/Entitlements.plist;
|
|
||||||
COPY_PHASE_STRIP = NO;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.tests.host.UIKit;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SDKROOT = iphoneos;
|
|
||||||
SWIFT_INSTALL_OBJC_HEADER = NO;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
63C9C4561D5D334800101ECE /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
BUNDLE_PACKAGE_TYPE = APPL;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = Tests/Entitlements.plist;
|
|
||||||
COPY_PHASE_STRIP = NO;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.promisekit.tests.host.UIKit;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SDKROOT = iphoneos;
|
|
||||||
SWIFT_INSTALL_OBJC_HEADER = NO;
|
|
||||||
SWIFT_VERSION = 4.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
|
||||||
630B2E101D5D0AF500DC10E9 /* Build configuration list for PBXNativeTarget "PMKALTests" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
630B2E111D5D0AF500DC10E9 /* Debug */,
|
|
||||||
630B2E121D5D0AF500DC10E9 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFA11D5BEE09003BAE60 /* Build configuration list for PBXProject "PMKAssetsLibrary" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFAD1D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFAE1D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C7FFAF1D5BEE09003BAE60 /* Build configuration list for PBXNativeTarget "PMKAssetsLibrary" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C7FFB01D5BEE09003BAE60 /* Debug */,
|
|
||||||
63C7FFB11D5BEE09003BAE60 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
63C9C4541D5D334800101ECE /* Build configuration list for PBXNativeTarget "PMKALTestsHost" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
63C9C4551D5D334800101ECE /* Debug */,
|
|
||||||
63C9C4561D5D334800101ECE /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
|
||||||
};
|
|
||||||
rootObject = 63C7FF9E1D5BEE09003BAE60 /* Project object */;
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Workspace
|
|
||||||
version = "1.0">
|
|
||||||
<FileRef
|
|
||||||
location = "self:/Users/mxcl/Desktop/PMK+UIKit/PMKFoundation.xcodeproj">
|
|
||||||
</FileRef>
|
|
||||||
</Workspace>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,127 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Scheme
|
|
||||||
LastUpgradeVersion = "1000"
|
|
||||||
version = "1.3">
|
|
||||||
<BuildAction
|
|
||||||
parallelizeBuildables = "YES"
|
|
||||||
buildImplicitDependencies = "NO">
|
|
||||||
<BuildActionEntries>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "NO"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAssetsLibrary.framework"
|
|
||||||
BlueprintName = "PMKAssetsLibrary"
|
|
||||||
ReferencedContainer = "container:PMKAssetsLibrary.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "NO"
|
|
||||||
buildForProfiling = "NO"
|
|
||||||
buildForArchiving = "NO"
|
|
||||||
buildForAnalyzing = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C9C4441D5D334700101ECE"
|
|
||||||
BuildableName = "PMKALTestsHost.app"
|
|
||||||
BlueprintName = "PMKALTestsHost"
|
|
||||||
ReferencedContainer = "container:PMKAssetsLibrary.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "NO"
|
|
||||||
buildForProfiling = "NO"
|
|
||||||
buildForArchiving = "NO"
|
|
||||||
buildForAnalyzing = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "630B2DFF1D5D0AF500DC10E9"
|
|
||||||
BuildableName = "PMKALTests.xctest"
|
|
||||||
BlueprintName = "PMKALTests"
|
|
||||||
ReferencedContainer = "container:PMKAssetsLibrary.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
||||||
<Testables>
|
|
||||||
<TestableReference
|
|
||||||
skipped = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "630B2DFF1D5D0AF500DC10E9"
|
|
||||||
BuildableName = "PMKALTests.xctest"
|
|
||||||
BlueprintName = "PMKALTests"
|
|
||||||
ReferencedContainer = "container:PMKAssetsLibrary.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</TestableReference>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAssetsLibrary.framework"
|
|
||||||
BlueprintName = "PMKAssetsLibrary"
|
|
||||||
ReferencedContainer = "container:PMKAssetsLibrary.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
|
||||||
<LaunchAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
launchStyle = "0"
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
|
||||||
debugDocumentVersioning = "YES"
|
|
||||||
debugServiceExtension = "internal"
|
|
||||||
allowLocationSimulation = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAssetsLibrary.framework"
|
|
||||||
BlueprintName = "PMKAssetsLibrary"
|
|
||||||
ReferencedContainer = "container:PMKAssetsLibrary.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
|
||||||
<ProfileAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
debugDocumentVersioning = "YES">
|
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "63C7FFA61D5BEE09003BAE60"
|
|
||||||
BuildableName = "PMKAssetsLibrary.framework"
|
|
||||||
BlueprintName = "PMKAssetsLibrary"
|
|
||||||
ReferencedContainer = "container:PMKAssetsLibrary.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
</ProfileAction>
|
|
||||||
<AnalyzeAction
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
</AnalyzeAction>
|
|
||||||
<ArchiveAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
revealArchiveInOrganizer = "YES">
|
|
||||||
</ArchiveAction>
|
|
||||||
</Scheme>
|
|
@@ -1,34 +0,0 @@
|
|||||||
# PromiseKit AssetsLibrary Extensions ![Build Status]
|
|
||||||
|
|
||||||
This project adds promises to Apple’s AssetsLibrary framework.
|
|
||||||
|
|
||||||
## CococaPods
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
pod "PromiseKit/AssetsLibrary" ~> 6.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into `PromiseKit.framework` thus nothing else is needed.
|
|
||||||
|
|
||||||
## Carthage
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
github "PromiseKit/AssetsLibrary" ~> 3.0
|
|
||||||
```
|
|
||||||
|
|
||||||
The extensions are built into their own framework:
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// swift
|
|
||||||
import PromiseKit
|
|
||||||
import PMKAssetsLibrary
|
|
||||||
```
|
|
||||||
|
|
||||||
```objc
|
|
||||||
// objc
|
|
||||||
@import PromiseKit;
|
|
||||||
@import PMKAssetsLibrary;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
[Build Status]: https://travis-ci.org/PromiseKit/AssetsLibrary.svg?branch=master
|
|
@@ -1,100 +0,0 @@
|
|||||||
import UIKit.UIViewController
|
|
||||||
import Foundation.NSData
|
|
||||||
import AssetsLibrary
|
|
||||||
#if !PMKCocoaPods
|
|
||||||
import PromiseKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
To import this `UIViewController` extension:
|
|
||||||
|
|
||||||
use_frameworks!
|
|
||||||
pod "PromiseKit/AssetsLibrary"
|
|
||||||
|
|
||||||
And then in your sources:
|
|
||||||
|
|
||||||
import PromiseKit
|
|
||||||
*/
|
|
||||||
extension UIViewController {
|
|
||||||
/**
|
|
||||||
- Returns: A promise that presents the provided UIImagePickerController and fulfills with the user selected media’s `NSData`.
|
|
||||||
*/
|
|
||||||
public func promise(_ vc: UIImagePickerController, animated: Bool = false, completion: (() -> Void)? = nil) -> Promise<NSData> {
|
|
||||||
let proxy = UIImagePickerControllerProxy()
|
|
||||||
vc.delegate = proxy
|
|
||||||
|
|
||||||
present(vc, animated: animated, completion: completion)
|
|
||||||
|
|
||||||
return proxy.promise.then(on: nil) { info -> Promise<NSData> in
|
|
||||||
#if swift(>=4.2)
|
|
||||||
let url = info[.referenceURL] as! URL
|
|
||||||
#else
|
|
||||||
let url = info[UIImagePickerControllerReferenceURL] as! URL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return Promise { seal in
|
|
||||||
ALAssetsLibrary().asset(for: url, resultBlock: { asset in
|
|
||||||
let N = Int(asset!.defaultRepresentation().size())
|
|
||||||
let bytes = UnsafeMutablePointer<UInt8>.allocate(capacity: N)
|
|
||||||
var error: NSError?
|
|
||||||
asset!.defaultRepresentation().getBytes(bytes, fromOffset: 0, length: N, error: &error)
|
|
||||||
|
|
||||||
if let error = error {
|
|
||||||
seal.reject(error)
|
|
||||||
} else {
|
|
||||||
seal.fulfill(NSData(bytesNoCopy: bytes, length: N))
|
|
||||||
}
|
|
||||||
}, failureBlock: { seal.reject($0!) } )
|
|
||||||
}
|
|
||||||
}.ensure {
|
|
||||||
self.dismiss(animated: animated, completion: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private class UIImagePickerControllerProxy: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
|
||||||
#if swift(>=4.2)
|
|
||||||
let (promise, seal) = Promise<[UIImagePickerController.InfoKey: Any]>.pending()
|
|
||||||
#else
|
|
||||||
let (promise, seal) = Promise<[String: Any]>.pending()
|
|
||||||
#endif
|
|
||||||
var retainCycle: AnyObject?
|
|
||||||
|
|
||||||
required override init() {
|
|
||||||
super.init()
|
|
||||||
retainCycle = self
|
|
||||||
}
|
|
||||||
|
|
||||||
#if swift(>=4.2)
|
|
||||||
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
|
|
||||||
seal.fulfill(info)
|
|
||||||
retainCycle = nil
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
|
|
||||||
seal.fulfill(info)
|
|
||||||
retainCycle = nil
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
|
||||||
seal.reject(UIImagePickerController.PMKError.cancelled)
|
|
||||||
retainCycle = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extension UIImagePickerController {
|
|
||||||
/// Errors representing PromiseKit UIImagePickerController failures
|
|
||||||
public enum PMKError: CancellableError {
|
|
||||||
/// The user cancelled the UIImagePickerController.
|
|
||||||
case cancelled
|
|
||||||
/// - Returns: true
|
|
||||||
public var isCancelled: Bool {
|
|
||||||
switch self {
|
|
||||||
case .cancelled:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.5 KiB |
@@ -1,12 +0,0 @@
|
|||||||
<?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>com.apple.private.tcc.allow</key>
|
|
||||||
<array>
|
|
||||||
<string>kTCCServiceAddressBook</string>
|
|
||||||
<string>kTCCServiceCalendar</string>
|
|
||||||
<string>kTCCServicePhotos</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,31 +0,0 @@
|
|||||||
import XCTest
|
|
||||||
|
|
||||||
class UIImagePickerControllerTests: XCTestCase {
|
|
||||||
func test_fulfills_with_data() {
|
|
||||||
let app = XCUIApplication()
|
|
||||||
let tablesQuery = app.tables
|
|
||||||
tablesQuery.staticTexts["1"].tap()
|
|
||||||
tablesQuery.children(matching: .cell).element(boundBy: 1).tap()
|
|
||||||
app.collectionViews.children(matching: .cell).element(boundBy: 0).tap()
|
|
||||||
|
|
||||||
XCTAssertTrue(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
var toggle: XCUIElement {
|
|
||||||
// calling this ensures that any other ViewController has dismissed
|
|
||||||
// as a side-effect since otherwise the switch won't be found
|
|
||||||
return XCUIApplication().tables.switches.element
|
|
||||||
}
|
|
||||||
|
|
||||||
var value: Bool {
|
|
||||||
return (toggle.value as! String) == "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
override func setUp() {
|
|
||||||
super.setUp()
|
|
||||||
continueAfterFailure = false
|
|
||||||
XCUIApplication().launch()
|
|
||||||
XCTAssertFalse(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user