* Note: It is possible that the permissions request interaction * with the user is interrupted. In this case you will receive empty permissions * and results arrays which should be treated as a cancellation. *
* * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}. * @param permissions The requested permissions. Never null. * @param grantResults The grant results for the corresponding permissions * which is either {@link PackageManager#PERMISSION_GRANTED} * or {@link PackageManager#PERMISSION_DENIED}. Never null. * @see #requestPermissions(String[], int) */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode != RC_HANDLE_CAMERA_PERM) { Log.d(TAG, "Got unexpected permission result: " + requestCode); super.onRequestPermissionsResult(requestCode, permissions, grantResults); return; } if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "Camera permission granted - initialize the camera source"); // we have permission, so create the camerasource createCameraSource(true); return; } Log.e(TAG, "Permission not granted: results len = " + grantResults.length + " Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)")); DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Face Tracker sample") .setMessage(R.string.no_camera_permission) .setPositiveButton(R.string.ok, listener) .show(); } /** * Starts or restarts the camera source, if it exists. If the camera source doesn't exist yet * (e.g., because onResume was called before the camera source was created), this will be called * again when the camera source is created. */ private void startCameraSource() { // check that the device has play services available. int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable( getApplicationContext()); if (code != ConnectionResult.SUCCESS) { Dialog dlg = GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS); dlg.show(); } if (mCameraSource != null) { try { mPreview.start(mCameraSource, mGraphicOverlay); } catch (IOException e) { Log.e(TAG, "Unable to start camera source.", e); mCameraSource.release(); mCameraSource = null; } } } @Override public void onFaceProximityTrigger(final Face face) { long timeSinceLastTrigger = System.currentTimeMillis() - mLastTriggerTime; if (timeSinceLastTrigger < TimeUnit.SECONDS.toMillis(NUM_SECONDS_WAIT_BETWEEN_RECOGNIZE)) return; alreadyRecognizedFacesList.add(face.getId()); mLastTriggerTime = System.currentTimeMillis(); mRecognitionAttempts = 1; recognize(true, false); } @Override public void onBackPressed() { super.onBackPressed(); finish(); } private void recognize(final boolean sayRecognizingMessage, final boolean repeat) { runOnUiThread(new Runnable() { @Override public void run() { Log.d(TAG, "Attempting to recognize"); mProgressBar.setVisibility(View.VISIBLE); if (sayRecognizingMessage) App.ttsObj.speak("Recognizing", TextToSpeech.QUEUE_ADD, null); try { mCameraSource.takePicture(new CameraSource.ShutterCallback() { @Override public void onShutter() { } }, new CameraSource.PictureCallback() { @Override public void onPictureTaken(final byte[] bytes) { new AsyncTask* * Supports scaling and mirroring of the graphics relative the camera's preview properties. The * idea is that detection items are expressed in terms of a preview size, but need to be scaled up * to the full view size, and also mirrored in the case of the front-facing camera.
* * Associated {@link Graphic} items should use the following methods to convert to view coordinates * for the graphics that are drawn: *
## License
Alamofire is released under the MIT license. See LICENSE for details.
================================================
FILE: iOS/Manager/EZShopManager/Pods/Alamofire/Source/AFError.swift
================================================
//
// AFError.swift
//
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Foundation
/// `AFError` is the error type returned by Alamofire. It encompasses a few different types of errors, each with
/// their own associated reasons.
///
/// - invalidURL: Returned when a `URLConvertible` type fails to create a valid `URL`.
/// - parameterEncodingFailed: Returned when a parameter encoding object throws an error during the encoding process.
/// - multipartEncodingFailed: Returned when some step in the multipart encoding process fails.
/// - responseValidationFailed: Returned when a `validate()` call fails.
/// - responseSerializationFailed: Returned when a response serializer encounters an error in the serialization process.
public enum AFError: Error {
/// The underlying reason the parameter encoding error occurred.
///
/// - missingURL: The URL request did not have a URL to encode.
/// - jsonEncodingFailed: JSON serialization failed with an underlying system error during the
/// encoding process.
/// - propertyListEncodingFailed: Property list serialization failed with an underlying system error during
/// encoding process.
public enum ParameterEncodingFailureReason {
case missingURL
case jsonEncodingFailed(error: Error)
case propertyListEncodingFailed(error: Error)
}
/// The underlying reason the multipart encoding error occurred.
///
/// - bodyPartURLInvalid: The `fileURL` provided for reading an encodable body part isn't a
/// file URL.
/// - bodyPartFilenameInvalid: The filename of the `fileURL` provided has either an empty
/// `lastPathComponent` or `pathExtension.
/// - bodyPartFileNotReachable: The file at the `fileURL` provided was not reachable.
/// - bodyPartFileNotReachableWithError: Attempting to check the reachability of the `fileURL` provided threw
/// an error.
/// - bodyPartFileIsDirectory: The file at the `fileURL` provided is actually a directory.
/// - bodyPartFileSizeNotAvailable: The size of the file at the `fileURL` provided was not returned by
/// the system.
/// - bodyPartFileSizeQueryFailedWithError: The attempt to find the size of the file at the `fileURL` provided
/// threw an error.
/// - bodyPartInputStreamCreationFailed: An `InputStream` could not be created for the provided `fileURL`.
/// - outputStreamCreationFailed: An `OutputStream` could not be created when attempting to write the
/// encoded data to disk.
/// - outputStreamFileAlreadyExists: The encoded body data could not be writtent disk because a file
/// already exists at the provided `fileURL`.
/// - outputStreamURLInvalid: The `fileURL` provided for writing the encoded body data to disk is
/// not a file URL.
/// - outputStreamWriteFailed: The attempt to write the encoded body data to disk failed with an
/// underlying error.
/// - inputStreamReadFailed: The attempt to read an encoded body part `InputStream` failed with
/// underlying system error.
public enum MultipartEncodingFailureReason {
case bodyPartURLInvalid(url: URL)
case bodyPartFilenameInvalid(in: URL)
case bodyPartFileNotReachable(at: URL)
case bodyPartFileNotReachableWithError(atURL: URL, error: Error)
case bodyPartFileIsDirectory(at: URL)
case bodyPartFileSizeNotAvailable(at: URL)
case bodyPartFileSizeQueryFailedWithError(forURL: URL, error: Error)
case bodyPartInputStreamCreationFailed(for: URL)
case outputStreamCreationFailed(for: URL)
case outputStreamFileAlreadyExists(at: URL)
case outputStreamURLInvalid(url: URL)
case outputStreamWriteFailed(error: Error)
case inputStreamReadFailed(error: Error)
}
/// The underlying reason the response validation error occurred.
///
/// - dataFileNil: The data file containing the server response did not exist.
/// - dataFileReadFailed: The data file containing the server response could not be read.
/// - missingContentType: The response did not contain a `Content-Type` and the `acceptableContentTypes`
/// provided did not contain wildcard type.
/// - unacceptableContentType: The response `Content-Type` did not match any type in the provided
/// `acceptableContentTypes`.
/// - unacceptableStatusCode: The response status code was not acceptable.
public enum ResponseValidationFailureReason {
case dataFileNil
case dataFileReadFailed(at: URL)
case missingContentType(acceptableContentTypes: [String])
case unacceptableContentType(acceptableContentTypes: [String], responseContentType: String)
case unacceptableStatusCode(code: Int)
}
/// The underlying reason the response serialization error occurred.
///
/// - inputDataNil: The server response contained no data.
/// - inputDataNilOrZeroLength: The server response contained no data or the data was zero length.
/// - inputFileNil: The file containing the server response did not exist.
/// - inputFileReadFailed: The file containing the server response could not be read.
/// - stringSerializationFailed: String serialization failed using the provided `String.Encoding`.
/// - jsonSerializationFailed: JSON serialization failed with an underlying system error.
/// - propertyListSerializationFailed: Property list serialization failed with an underlying system error.
public enum ResponseSerializationFailureReason {
case inputDataNil
case inputDataNilOrZeroLength
case inputFileNil
case inputFileReadFailed(at: URL)
case stringSerializationFailed(encoding: String.Encoding)
case jsonSerializationFailed(error: Error)
case propertyListSerializationFailed(error: Error)
}
case invalidURL(url: URLConvertible)
case parameterEncodingFailed(reason: ParameterEncodingFailureReason)
case multipartEncodingFailed(reason: MultipartEncodingFailureReason)
case responseValidationFailed(reason: ResponseValidationFailureReason)
case responseSerializationFailed(reason: ResponseSerializationFailureReason)
}
// MARK: - Adapt Error
struct AdaptError: Error {
let error: Error
}
extension Error {
var underlyingAdaptError: Error? { return (self as? AdaptError)?.error }
}
// MARK: - Error Booleans
extension AFError {
/// Returns whether the AFError is an invalid URL error.
public var isInvalidURLError: Bool {
if case .invalidURL = self { return true }
return false
}
/// Returns whether the AFError is a parameter encoding error. When `true`, the `underlyingError` property will
/// contain the associated value.
public var isParameterEncodingError: Bool {
if case .parameterEncodingFailed = self { return true }
return false
}
/// Returns whether the AFError is a multipart encoding error. When `true`, the `url` and `underlyingError` properties
/// will contain the associated values.
public var isMultipartEncodingError: Bool {
if case .multipartEncodingFailed = self { return true }
return false
}
/// Returns whether the `AFError` is a response validation error. When `true`, the `acceptableContentTypes`,
/// `responseContentType`, and `responseCode` properties will contain the associated values.
public var isResponseValidationError: Bool {
if case .responseValidationFailed = self { return true }
return false
}
/// Returns whether the `AFError` is a response serialization error. When `true`, the `failedStringEncoding` and
/// `underlyingError` properties will contain the associated values.
public var isResponseSerializationError: Bool {
if case .responseSerializationFailed = self { return true }
return false
}
}
// MARK: - Convenience Properties
extension AFError {
/// The `URLConvertible` associated with the error.
public var urlConvertible: URLConvertible? {
switch self {
case .invalidURL(let url):
return url
default:
return nil
}
}
/// The `URL` associated with the error.
public var url: URL? {
switch self {
case .multipartEncodingFailed(let reason):
return reason.url
default:
return nil
}
}
/// The `Error` returned by a system framework associated with a `.parameterEncodingFailed`,
/// `.multipartEncodingFailed` or `.responseSerializationFailed` error.
public var underlyingError: Error? {
switch self {
case .parameterEncodingFailed(let reason):
return reason.underlyingError
case .multipartEncodingFailed(let reason):
return reason.underlyingError
case .responseSerializationFailed(let reason):
return reason.underlyingError
default:
return nil
}
}
/// The acceptable `Content-Type`s of a `.responseValidationFailed` error.
public var acceptableContentTypes: [String]? {
switch self {
case .responseValidationFailed(let reason):
return reason.acceptableContentTypes
default:
return nil
}
}
/// The response `Content-Type` of a `.responseValidationFailed` error.
public var responseContentType: String? {
switch self {
case .responseValidationFailed(let reason):
return reason.responseContentType
default:
return nil
}
}
/// The response code of a `.responseValidationFailed` error.
public var responseCode: Int? {
switch self {
case .responseValidationFailed(let reason):
return reason.responseCode
default:
return nil
}
}
/// The `String.Encoding` associated with a failed `.stringResponse()` call.
public var failedStringEncoding: String.Encoding? {
switch self {
case .responseSerializationFailed(let reason):
return reason.failedStringEncoding
default:
return nil
}
}
}
extension AFError.ParameterEncodingFailureReason {
var underlyingError: Error? {
switch self {
case .jsonEncodingFailed(let error), .propertyListEncodingFailed(let error):
return error
default:
return nil
}
}
}
extension AFError.MultipartEncodingFailureReason {
var url: URL? {
switch self {
case .bodyPartURLInvalid(let url), .bodyPartFilenameInvalid(let url), .bodyPartFileNotReachable(let url),
.bodyPartFileIsDirectory(let url), .bodyPartFileSizeNotAvailable(let url),
.bodyPartInputStreamCreationFailed(let url), .outputStreamCreationFailed(let url),
.outputStreamFileAlreadyExists(let url), .outputStreamURLInvalid(let url),
.bodyPartFileNotReachableWithError(let url, _), .bodyPartFileSizeQueryFailedWithError(let url, _):
return url
default:
return nil
}
}
var underlyingError: Error? {
switch self {
case .bodyPartFileNotReachableWithError(_, let error), .bodyPartFileSizeQueryFailedWithError(_, let error),
.outputStreamWriteFailed(let error), .inputStreamReadFailed(let error):
return error
default:
return nil
}
}
}
extension AFError.ResponseValidationFailureReason {
var acceptableContentTypes: [String]? {
switch self {
case .missingContentType(let types), .unacceptableContentType(let types, _):
return types
default:
return nil
}
}
var responseContentType: String? {
switch self {
case .unacceptableContentType(_, let responseType):
return responseType
default:
return nil
}
}
var responseCode: Int? {
switch self {
case .unacceptableStatusCode(let code):
return code
default:
return nil
}
}
}
extension AFError.ResponseSerializationFailureReason {
var failedStringEncoding: String.Encoding? {
switch self {
case .stringSerializationFailed(let encoding):
return encoding
default:
return nil
}
}
var underlyingError: Error? {
switch self {
case .jsonSerializationFailed(let error), .propertyListSerializationFailed(let error):
return error
default:
return nil
}
}
}
// MARK: - Error Descriptions
extension AFError: LocalizedError {
public var errorDescription: String? {
switch self {
case .invalidURL(let url):
return "URL is not valid: \(url)"
case .parameterEncodingFailed(let reason):
return reason.localizedDescription
case .multipartEncodingFailed(let reason):
return reason.localizedDescription
case .responseValidationFailed(let reason):
return reason.localizedDescription
case .responseSerializationFailed(let reason):
return reason.localizedDescription
}
}
}
extension AFError.ParameterEncodingFailureReason {
var localizedDescription: String {
switch self {
case .missingURL:
return "URL request to encode was missing a URL"
case .jsonEncodingFailed(let error):
return "JSON could not be encoded because of error:\n\(error.localizedDescription)"
case .propertyListEncodingFailed(let error):
return "PropertyList could not be encoded because of error:\n\(error.localizedDescription)"
}
}
}
extension AFError.MultipartEncodingFailureReason {
var localizedDescription: String {
switch self {
case .bodyPartURLInvalid(let url):
return "The URL provided is not a file URL: \(url)"
case .bodyPartFilenameInvalid(let url):
return "The URL provided does not have a valid filename: \(url)"
case .bodyPartFileNotReachable(let url):
return "The URL provided is not reachable: \(url)"
case .bodyPartFileNotReachableWithError(let url, let error):
return (
"The system returned an error while checking the provided URL for " +
"reachability.\nURL: \(url)\nError: \(error)"
)
case .bodyPartFileIsDirectory(let url):
return "The URL provided is a directory: \(url)"
case .bodyPartFileSizeNotAvailable(let url):
return "Could not fetch the file size from the provided URL: \(url)"
case .bodyPartFileSizeQueryFailedWithError(let url, let error):
return (
"The system returned an error while attempting to fetch the file size from the " +
"provided URL.\nURL: \(url)\nError: \(error)"
)
case .bodyPartInputStreamCreationFailed(let url):
return "Failed to create an InputStream for the provided URL: \(url)"
case .outputStreamCreationFailed(let url):
return "Failed to create an OutputStream for URL: \(url)"
case .outputStreamFileAlreadyExists(let url):
return "A file already exists at the provided URL: \(url)"
case .outputStreamURLInvalid(let url):
return "The provided OutputStream URL is invalid: \(url)"
case .outputStreamWriteFailed(let error):
return "OutputStream write failed with error: \(error)"
case .inputStreamReadFailed(let error):
return "InputStream read failed with error: \(error)"
}
}
}
extension AFError.ResponseSerializationFailureReason {
var localizedDescription: String {
switch self {
case .inputDataNil:
return "Response could not be serialized, input data was nil."
case .inputDataNilOrZeroLength:
return "Response could not be serialized, input data was nil or zero length."
case .inputFileNil:
return "Response could not be serialized, input file was nil."
case .inputFileReadFailed(let url):
return "Response could not be serialized, input file could not be read: \(url)."
case .stringSerializationFailed(let encoding):
return "String could not be serialized with encoding: \(encoding)."
case .jsonSerializationFailed(let error):
return "JSON could not be serialized because of error:\n\(error.localizedDescription)"
case .propertyListSerializationFailed(let error):
return "PropertyList could not be serialized because of error:\n\(error.localizedDescription)"
}
}
}
extension AFError.ResponseValidationFailureReason {
var localizedDescription: String {
switch self {
case .dataFileNil:
return "Response could not be validated, data file was nil."
case .dataFileReadFailed(let url):
return "Response could not be validated, data file could not be read: \(url)."
case .missingContentType(let types):
return (
"Response Content-Type was missing and acceptable content types " +
"(\(types.joined(separator: ","))) do not match \"*/*\"."
)
case .unacceptableContentType(let acceptableTypes, let responseType):
return (
"Response Content-Type \"\(responseType)\" does not match any acceptable types: " +
"\(acceptableTypes.joined(separator: ","))."
)
case .unacceptableStatusCode(let code):
return "Response status code was unacceptable: \(code)."
}
}
}
================================================
FILE: iOS/Manager/EZShopManager/Pods/Alamofire/Source/Alamofire.swift
================================================
//
// Alamofire.swift
//
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Foundation
/// Types adopting the `URLConvertible` protocol can be used to construct URLs, which are then used to construct
/// URL requests.
public protocol URLConvertible {
/// Returns a URL that conforms to RFC 2396 or throws an `Error`.
///
/// - throws: An `Error` if the type cannot be converted to a `URL`.
///
/// - returns: A URL or throws an `Error`.
func asURL() throws -> URL
}
extension String: URLConvertible {
/// Returns a URL if `self` represents a valid URL string that conforms to RFC 2396 or throws an `AFError`.
///
/// - throws: An `AFError.invalidURL` if `self` is not a valid URL string.
///
/// - returns: A URL or throws an `AFError`.
public func asURL() throws -> URL {
guard let url = URL(string: self) else { throw AFError.invalidURL(url: self) }
return url
}
}
extension URL: URLConvertible {
/// Returns self.
public func asURL() throws -> URL { return self }
}
extension URLComponents: URLConvertible {
/// Returns a URL if `url` is not nil, otherise throws an `Error`.
///
/// - throws: An `AFError.invalidURL` if `url` is `nil`.
///
/// - returns: A URL or throws an `AFError`.
public func asURL() throws -> URL {
guard let url = url else { throw AFError.invalidURL(url: self) }
return url
}
}
// MARK: -
/// Types adopting the `URLRequestConvertible` protocol can be used to construct URL requests.
public protocol URLRequestConvertible {
/// Returns a URL request or throws if an `Error` was encountered.
///
/// - throws: An `Error` if the underlying `URLRequest` is `nil`.
///
/// - returns: A URL request.
func asURLRequest() throws -> URLRequest
}
extension URLRequestConvertible {
/// The URL request.
public var urlRequest: URLRequest? { return try? asURLRequest() }
}
extension URLRequest: URLRequestConvertible {
/// Returns a URL request or throws if an `Error` was encountered.
public func asURLRequest() throws -> URLRequest { return self }
}
// MARK: -
extension URLRequest {
/// Creates an instance with the specified `method`, `urlString` and `headers`.
///
/// - parameter url: The URL.
/// - parameter method: The HTTP method.
/// - parameter headers: The HTTP headers. `nil` by default.
///
/// - returns: The new `URLRequest` instance.
public init(url: URLConvertible, method: HTTPMethod, headers: HTTPHeaders? = nil) throws {
let url = try url.asURL()
self.init(url: url)
httpMethod = method.rawValue
if let headers = headers {
for (headerField, headerValue) in headers {
setValue(headerValue, forHTTPHeaderField: headerField)
}
}
}
func adapt(using adapter: RequestAdapter?) throws -> URLRequest {
guard let adapter = adapter else { return self }
return try adapter.adapt(self)
}
}
// MARK: - Data Request
/// Creates a `DataRequest` using the default `SessionManager` to retrieve the contents of the specified `url`,
/// `method`, `parameters`, `encoding` and `headers`.
///
/// - parameter url: The URL.
/// - parameter method: The HTTP method. `.get` by default.
/// - parameter parameters: The parameters. `nil` by default.
/// - parameter encoding: The parameter encoding. `URLEncoding.default` by default.
/// - parameter headers: The HTTP headers. `nil` by default.
///
/// - returns: The created `DataRequest`.
@discardableResult
public func request(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)
-> DataRequest
{
return SessionManager.default.request(
url,
method: method,
parameters: parameters,
encoding: encoding,
headers: headers
)
}
/// Creates a `DataRequest` using the default `SessionManager` to retrieve the contents of a URL based on the
/// specified `urlRequest`.
///
/// - parameter urlRequest: The URL request
///
/// - returns: The created `DataRequest`.
@discardableResult
public func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
return SessionManager.default.request(urlRequest)
}
// MARK: - Download Request
// MARK: URL Request
/// Creates a `DownloadRequest` using the default `SessionManager` to retrieve the contents of the specified `url`,
/// `method`, `parameters`, `encoding`, `headers` and save them to the `destination`.
///
/// If `destination` is not specified, the contents will remain in the temporary location determined by the
/// underlying URL session.
///
/// - parameter url: The URL.
/// - parameter method: The HTTP method. `.get` by default.
/// - parameter parameters: The parameters. `nil` by default.
/// - parameter encoding: The parameter encoding. `URLEncoding.default` by default.
/// - parameter headers: The HTTP headers. `nil` by default.
/// - parameter destination: The closure used to determine the destination of the downloaded file. `nil` by default.
///
/// - returns: The created `DownloadRequest`.
@discardableResult
public func download(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil,
to destination: DownloadRequest.DownloadFileDestination? = nil)
-> DownloadRequest
{
return SessionManager.default.download(
url,
method: method,
parameters: parameters,
encoding: encoding,
headers: headers,
to: destination
)
}
/// Creates a `DownloadRequest` using the default `SessionManager` to retrieve the contents of a URL based on the
/// specified `urlRequest` and save them to the `destination`.
///
/// If `destination` is not specified, the contents will remain in the temporary location determined by the
/// underlying URL session.
///
/// - parameter urlRequest: The URL request.
/// - parameter destination: The closure used to determine the destination of the downloaded file. `nil` by default.
///
/// - returns: The created `DownloadRequest`.
@discardableResult
public func download(
_ urlRequest: URLRequestConvertible,
to destination: DownloadRequest.DownloadFileDestination? = nil)
-> DownloadRequest
{
return SessionManager.default.download(urlRequest, to: destination)
}
// MARK: Resume Data
/// Creates a `DownloadRequest` using the default `SessionManager` from the `resumeData` produced from a
/// previous request cancellation to retrieve the contents of the original request and save them to the `destination`.
///
/// If `destination` is not specified, the contents will remain in the temporary location determined by the
/// underlying URL session.
///
/// On the latest release of all the Apple platforms (iOS 10, macOS 10.12, tvOS 10, watchOS 3), `resumeData` is broken
/// on background URL session configurations. There's an underlying bug in the `resumeData` generation logic where the
/// data is written incorrectly and will always fail to resume the download. For more information about the bug and
/// possible workarounds, please refer to the following Stack Overflow post:
///
/// - http://stackoverflow.com/a/39347461/1342462
///
/// - parameter resumeData: The resume data. This is an opaque data blob produced by `URLSessionDownloadTask`
/// when a task is cancelled. See `URLSession -downloadTask(withResumeData:)` for additional
/// information.
/// - parameter destination: The closure used to determine the destination of the downloaded file. `nil` by default.
///
/// - returns: The created `DownloadRequest`.
@discardableResult
public func download(
resumingWith resumeData: Data,
to destination: DownloadRequest.DownloadFileDestination? = nil)
-> DownloadRequest
{
return SessionManager.default.download(resumingWith: resumeData, to: destination)
}
// MARK: - Upload Request
// MARK: File
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `url`, `method` and `headers`
/// for uploading the `file`.
///
/// - parameter file: The file to upload.
/// - parameter url: The URL.
/// - parameter method: The HTTP method. `.post` by default.
/// - parameter headers: The HTTP headers. `nil` by default.
///
/// - returns: The created `UploadRequest`.
@discardableResult
public func upload(
_ fileURL: URL,
to url: URLConvertible,
method: HTTPMethod = .post,
headers: HTTPHeaders? = nil)
-> UploadRequest
{
return SessionManager.default.upload(fileURL, to: url, method: method, headers: headers)
}
/// Creates a `UploadRequest` using the default `SessionManager` from the specified `urlRequest` for
/// uploading the `file`.
///
/// - parameter file: The file to upload.
/// - parameter urlRequest: The URL request.
///
/// - returns: The created `UploadRequest`.
@discardableResult
public func upload(_ fileURL: URL, with urlRequest: URLRequestConvertible) -> UploadRequest {
return SessionManager.default.upload(fileURL, with: urlRequest)
}
// MARK: Data
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `url`, `method` and `headers`
/// for uploading the `data`.
///
/// - parameter data: The data to upload.
/// - parameter url: The URL.
/// - parameter method: The HTTP method. `.post` by default.
/// - parameter headers: The HTTP headers. `nil` by default.
///
/// - returns: The created `UploadRequest`.
@discardableResult
public func upload(
_ data: Data,
to url: URLConvertible,
method: HTTPMethod = .post,
headers: HTTPHeaders? = nil)
-> UploadRequest
{
return SessionManager.default.upload(data, to: url, method: method, headers: headers)
}
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `urlRequest` for
/// uploading the `data`.
///
/// - parameter data: The data to upload.
/// - parameter urlRequest: The URL request.
///
/// - returns: The created `UploadRequest`.
@discardableResult
public func upload(_ data: Data, with urlRequest: URLRequestConvertible) -> UploadRequest {
return SessionManager.default.upload(data, with: urlRequest)
}
// MARK: InputStream
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `url`, `method` and `headers`
/// for uploading the `stream`.
///
/// - parameter stream: The stream to upload.
/// - parameter url: The URL.
/// - parameter method: The HTTP method. `.post` by default.
/// - parameter headers: The HTTP headers. `nil` by default.
///
/// - returns: The created `UploadRequest`.
@discardableResult
public func upload(
_ stream: InputStream,
to url: URLConvertible,
method: HTTPMethod = .post,
headers: HTTPHeaders? = nil)
-> UploadRequest
{
return SessionManager.default.upload(stream, to: url, method: method, headers: headers)
}
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `urlRequest` for
/// uploading the `stream`.
///
/// - parameter urlRequest: The URL request.
/// - parameter stream: The stream to upload.
///
/// - returns: The created `UploadRequest`.
@discardableResult
public func upload(_ stream: InputStream, with urlRequest: URLRequestConvertible) -> UploadRequest {
return SessionManager.default.upload(stream, with: urlRequest)
}
// MARK: MultipartFormData
/// Encodes `multipartFormData` using `encodingMemoryThreshold` with the default `SessionManager` and calls
/// `encodingCompletion` with new `UploadRequest` using the `url`, `method` and `headers`.
///
/// It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative
/// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
/// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
/// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
/// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
/// used for larger payloads such as video content.
///
/// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
/// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
/// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
/// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
/// technique was used.
///
/// - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
/// - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
/// `multipartFormDataEncodingMemoryThreshold` by default.
/// - parameter url: The URL.
/// - parameter method: The HTTP method. `.post` by default.
/// - parameter headers: The HTTP headers. `nil` by default.
/// - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
public func upload(
multipartFormData: @escaping (MultipartFormData) -> Void,
usingThreshold encodingMemoryThreshold: UInt64 = SessionManager.multipartFormDataEncodingMemoryThreshold,
to url: URLConvertible,
method: HTTPMethod = .post,
headers: HTTPHeaders? = nil,
encodingCompletion: ((SessionManager.MultipartFormDataEncodingResult) -> Void)?)
{
return SessionManager.default.upload(
multipartFormData: multipartFormData,
usingThreshold: encodingMemoryThreshold,
to: url,
method: method,
headers: headers,
encodingCompletion: encodingCompletion
)
}
/// Encodes `multipartFormData` using `encodingMemoryThreshold` and the default `SessionManager` and
/// calls `encodingCompletion` with new `UploadRequest` using the `urlRequest`.
///
/// It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative
/// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
/// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
/// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
/// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
/// used for larger payloads such as video content.
///
/// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
/// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
/// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
/// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
/// technique was used.
///
/// - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
/// - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
/// `multipartFormDataEncodingMemoryThreshold` by default.
/// - parameter urlRequest: The URL request.
/// - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
public func upload(
multipartFormData: @escaping (MultipartFormData) -> Void,
usingThreshold encodingMemoryThreshold: UInt64 = SessionManager.multipartFormDataEncodingMemoryThreshold,
with urlRequest: URLRequestConvertible,
encodingCompletion: ((SessionManager.MultipartFormDataEncodingResult) -> Void)?)
{
return SessionManager.default.upload(
multipartFormData: multipartFormData,
usingThreshold: encodingMemoryThreshold,
with: urlRequest,
encodingCompletion: encodingCompletion
)
}
#if !os(watchOS)
// MARK: - Stream Request
// MARK: Hostname and Port
/// Creates a `StreamRequest` using the default `SessionManager` for bidirectional streaming with the `hostname`
/// and `port`.
///
/// If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
///
/// - parameter hostName: The hostname of the server to connect to.
/// - parameter port: The port of the server to connect to.
///
/// - returns: The created `StreamRequest`.
@discardableResult
@available(iOS 9.0, macOS 10.11, tvOS 9.0, *)
public func stream(withHostName hostName: String, port: Int) -> StreamRequest {
return SessionManager.default.stream(withHostName: hostName, port: port)
}
// MARK: NetService
/// Creates a `StreamRequest` using the default `SessionManager` for bidirectional streaming with the `netService`.
///
/// If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
///
/// - parameter netService: The net service used to identify the endpoint.
///
/// - returns: The created `StreamRequest`.
@discardableResult
@available(iOS 9.0, macOS 10.11, tvOS 9.0, *)
public func stream(with netService: NetService) -> StreamRequest {
return SessionManager.default.stream(with: netService)
}
#endif
================================================
FILE: iOS/Manager/EZShopManager/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift
================================================
//
// DispatchQueue+Alamofire.swift
//
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Dispatch
import Foundation
extension DispatchQueue {
static var userInteractive: DispatchQueue { return DispatchQueue.global(qos: .userInteractive) }
static var userInitiated: DispatchQueue { return DispatchQueue.global(qos: .userInitiated) }
static var utility: DispatchQueue { return DispatchQueue.global(qos: .utility) }
static var background: DispatchQueue { return DispatchQueue.global(qos: .background) }
func after(_ delay: TimeInterval, execute closure: @escaping () -> Void) {
asyncAfter(deadline: .now() + delay, execute: closure)
}
}
================================================
FILE: iOS/Manager/EZShopManager/Pods/Alamofire/Source/MultipartFormData.swift
================================================
//
// MultipartFormData.swift
//
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Foundation
#if os(iOS) || os(watchOS) || os(tvOS)
import MobileCoreServices
#elseif os(macOS)
import CoreServices
#endif
/// Constructs `multipart/form-data` for uploads within an HTTP or HTTPS body. There are currently two ways to encode
/// multipart form data. The first way is to encode the data directly in memory. This is very efficient, but can lead
/// to memory issues if the dataset is too large. The second way is designed for larger datasets and will write all the
/// data to a single file on disk with all the proper boundary segmentation. The second approach MUST be used for
/// larger datasets such as video content, otherwise your app may run out of memory when trying to encode the dataset.
///
/// For more information on `multipart/form-data` in general, please refer to the RFC-2388 and RFC-2045 specs as well
/// and the w3 form documentation.
///
/// - https://www.ietf.org/rfc/rfc2388.txt
/// - https://www.ietf.org/rfc/rfc2045.txt
/// - https://www.w3.org/TR/html401/interact/forms.html#h-17.13
open class MultipartFormData {
// MARK: - Helper Types
struct EncodingCharacters {
static let crlf = "\r\n"
}
struct BoundaryGenerator {
enum BoundaryType {
case initial, encapsulated, final
}
static func randomBoundary() -> String {
return String(format: "alamofire.boundary.%08x%08x", arc4random(), arc4random())
}
static func boundaryData(forBoundaryType boundaryType: BoundaryType, boundary: String) -> Data {
let boundaryText: String
switch boundaryType {
case .initial:
boundaryText = "--\(boundary)\(EncodingCharacters.crlf)"
case .encapsulated:
boundaryText = "\(EncodingCharacters.crlf)--\(boundary)\(EncodingCharacters.crlf)"
case .final:
boundaryText = "\(EncodingCharacters.crlf)--\(boundary)--\(EncodingCharacters.crlf)"
}
return boundaryText.data(using: String.Encoding.utf8, allowLossyConversion: false)!
}
}
class BodyPart {
let headers: HTTPHeaders
let bodyStream: InputStream
let bodyContentLength: UInt64
var hasInitialBoundary = false
var hasFinalBoundary = false
init(headers: HTTPHeaders, bodyStream: InputStream, bodyContentLength: UInt64) {
self.headers = headers
self.bodyStream = bodyStream
self.bodyContentLength = bodyContentLength
}
}
// MARK: - Properties
/// The `Content-Type` header value containing the boundary used to generate the `multipart/form-data`.
open var contentType: String { return "multipart/form-data; boundary=\(boundary)" }
/// The content length of all body parts used to generate the `multipart/form-data` not including the boundaries.
public var contentLength: UInt64 { return bodyParts.reduce(0) { $0 + $1.bodyContentLength } }
/// The boundary used to separate the body parts in the encoded form data.
public let boundary: String
private var bodyParts: [BodyPart]
private var bodyPartError: AFError?
private let streamBufferSize: Int
// MARK: - Lifecycle
/// Creates a multipart form data object.
///
/// - returns: The multipart form data object.
public init() {
self.boundary = BoundaryGenerator.randomBoundary()
self.bodyParts = []
///
/// The optimal read/write buffer size in bytes for input and output streams is 1024 (1KB). For more
/// information, please refer to the following article:
/// - https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Streams/Articles/ReadingInputStreams.html
///
self.streamBufferSize = 1024
}
// MARK: - Body Parts
/// Creates a body part from the data and appends it to the multipart form data object.
///
/// The body part data will be encoded using the following format:
///
/// - `Content-Disposition: form-data; name=#{name}` (HTTP Header)
/// - Encoded data
/// - Multipart form boundary
///
/// - parameter data: The data to encode into the multipart form data.
/// - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
public func append(_ data: Data, withName name: String) {
let headers = contentHeaders(withName: name)
let stream = InputStream(data: data)
let length = UInt64(data.count)
append(stream, withLength: length, headers: headers)
}
/// Creates a body part from the data and appends it to the multipart form data object.
///
/// The body part data will be encoded using the following format:
///
/// - `Content-Disposition: form-data; name=#{name}` (HTTP Header)
/// - `Content-Type: #{generated mimeType}` (HTTP Header)
/// - Encoded data
/// - Multipart form boundary
///
/// - parameter data: The data to encode into the multipart form data.
/// - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
/// - parameter mimeType: The MIME type to associate with the data content type in the `Content-Type` HTTP header.
public func append(_ data: Data, withName name: String, mimeType: String) {
let headers = contentHeaders(withName: name, mimeType: mimeType)
let stream = InputStream(data: data)
let length = UInt64(data.count)
append(stream, withLength: length, headers: headers)
}
/// Creates a body part from the data and appends it to the multipart form data object.
///
/// The body part data will be encoded using the following format:
///
/// - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header)
/// - `Content-Type: #{mimeType}` (HTTP Header)
/// - Encoded file data
/// - Multipart form boundary
///
/// - parameter data: The data to encode into the multipart form data.
/// - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
/// - parameter fileName: The filename to associate with the data in the `Content-Disposition` HTTP header.
/// - parameter mimeType: The MIME type to associate with the data in the `Content-Type` HTTP header.
public func append(_ data: Data, withName name: String, fileName: String, mimeType: String) {
let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType)
let stream = InputStream(data: data)
let length = UInt64(data.count)
append(stream, withLength: length, headers: headers)
}
/// Creates a body part from the file and appends it to the multipart form data object.
///
/// The body part data will be encoded using the following format:
///
/// - `Content-Disposition: form-data; name=#{name}; filename=#{generated filename}` (HTTP Header)
/// - `Content-Type: #{generated mimeType}` (HTTP Header)
/// - Encoded file data
/// - Multipart form boundary
///
/// The filename in the `Content-Disposition` HTTP header is generated from the last path component of the
/// `fileURL`. The `Content-Type` HTTP header MIME type is generated by mapping the `fileURL` extension to the
/// system associated MIME type.
///
/// - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data.
/// - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header.
public func append(_ fileURL: URL, withName name: String) {
let fileName = fileURL.lastPathComponent
let pathExtension = fileURL.pathExtension
if !fileName.isEmpty && !pathExtension.isEmpty {
let mime = mimeType(forPathExtension: pathExtension)
append(fileURL, withName: name, fileName: fileName, mimeType: mime)
} else {
setBodyPartError(withReason: .bodyPartFilenameInvalid(in: fileURL))
}
}
/// Creates a body part from the file and appends it to the multipart form data object.
///
/// The body part data will be encoded using the following format:
///
/// - Content-Disposition: form-data; name=#{name}; filename=#{filename} (HTTP Header)
/// - Content-Type: #{mimeType} (HTTP Header)
/// - Encoded file data
/// - Multipart form boundary
///
/// - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data.
/// - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header.
/// - parameter fileName: The filename to associate with the file content in the `Content-Disposition` HTTP header.
/// - parameter mimeType: The MIME type to associate with the file content in the `Content-Type` HTTP header.
public func append(_ fileURL: URL, withName name: String, fileName: String, mimeType: String) {
let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType)
//============================================================
// Check 1 - is file URL?
//============================================================
guard fileURL.isFileURL else {
setBodyPartError(withReason: .bodyPartURLInvalid(url: fileURL))
return
}
//============================================================
// Check 2 - is file URL reachable?
//============================================================
do {
let isReachable = try fileURL.checkPromisedItemIsReachable()
guard isReachable else {
setBodyPartError(withReason: .bodyPartFileNotReachable(at: fileURL))
return
}
} catch {
setBodyPartError(withReason: .bodyPartFileNotReachableWithError(atURL: fileURL, error: error))
return
}
//============================================================
// Check 3 - is file URL a directory?
//============================================================
var isDirectory: ObjCBool = false
let path = fileURL.path
guard FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory) && !isDirectory.boolValue else
{
setBodyPartError(withReason: .bodyPartFileIsDirectory(at: fileURL))
return
}
//============================================================
// Check 4 - can the file size be extracted?
//============================================================
let bodyContentLength: UInt64
do {
guard let fileSize = try FileManager.default.attributesOfItem(atPath: path)[.size] as? NSNumber else {
setBodyPartError(withReason: .bodyPartFileSizeNotAvailable(at: fileURL))
return
}
bodyContentLength = fileSize.uint64Value
}
catch {
setBodyPartError(withReason: .bodyPartFileSizeQueryFailedWithError(forURL: fileURL, error: error))
return
}
//============================================================
// Check 5 - can a stream be created from file URL?
//============================================================
guard let stream = InputStream(url: fileURL) else {
setBodyPartError(withReason: .bodyPartInputStreamCreationFailed(for: fileURL))
return
}
append(stream, withLength: bodyContentLength, headers: headers)
}
/// Creates a body part from the stream and appends it to the multipart form data object.
///
/// The body part data will be encoded using the following format:
///
/// - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header)
/// - `Content-Type: #{mimeType}` (HTTP Header)
/// - Encoded stream data
/// - Multipart form boundary
///
/// - parameter stream: The input stream to encode in the multipart form data.
/// - parameter length: The content length of the stream.
/// - parameter name: The name to associate with the stream content in the `Content-Disposition` HTTP header.
/// - parameter fileName: The filename to associate with the stream content in the `Content-Disposition` HTTP header.
/// - parameter mimeType: The MIME type to associate with the stream content in the `Content-Type` HTTP header.
public func append(
_ stream: InputStream,
withLength length: UInt64,
name: String,
fileName: String,
mimeType: String)
{
let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType)
append(stream, withLength: length, headers: headers)
}
/// Creates a body part with the headers, stream and length and appends it to the multipart form data object.
///
/// The body part data will be encoded using the following format:
///
/// - HTTP headers
/// - Encoded stream data
/// - Multipart form boundary
///
/// - parameter stream: The input stream to encode in the multipart form data.
/// - parameter length: The content length of the stream.
/// - parameter headers: The HTTP headers for the body part.
public func append(_ stream: InputStream, withLength length: UInt64, headers: HTTPHeaders) {
let bodyPart = BodyPart(headers: headers, bodyStream: stream, bodyContentLength: length)
bodyParts.append(bodyPart)
}
// MARK: - Data Encoding
/// Encodes all the appended body parts into a single `Data` value.
///
/// It is important to note that this method will load all the appended body parts into memory all at the same
/// time. This method should only be used when the encoded data will have a small memory footprint. For large data
/// cases, please use the `writeEncodedDataToDisk(fileURL:completionHandler:)` method.
///
/// - throws: An `AFError` if encoding encounters an error.
///
/// - returns: The encoded `Data` if encoding is successful.
public func encode() throws -> Data {
if let bodyPartError = bodyPartError {
throw bodyPartError
}
var encoded = Data()
bodyParts.first?.hasInitialBoundary = true
bodyParts.last?.hasFinalBoundary = true
for bodyPart in bodyParts {
let encodedData = try encode(bodyPart)
encoded.append(encodedData)
}
return encoded
}
/// Writes the appended body parts into the given file URL.
///
/// This process is facilitated by reading and writing with input and output streams, respectively. Thus,
/// this approach is very memory efficient and should be used for large body part data.
///
/// - parameter fileURL: The file URL to write the multipart form data into.
///
/// - throws: An `AFError` if encoding encounters an error.
public func writeEncodedData(to fileURL: URL) throws {
if let bodyPartError = bodyPartError {
throw bodyPartError
}
if FileManager.default.fileExists(atPath: fileURL.path) {
throw AFError.multipartEncodingFailed(reason: .outputStreamFileAlreadyExists(at: fileURL))
} else if !fileURL.isFileURL {
throw AFError.multipartEncodingFailed(reason: .outputStreamURLInvalid(url: fileURL))
}
guard let outputStream = OutputStream(url: fileURL, append: false) else {
throw AFError.multipartEncodingFailed(reason: .outputStreamCreationFailed(for: fileURL))
}
outputStream.open()
defer { outputStream.close() }
self.bodyParts.first?.hasInitialBoundary = true
self.bodyParts.last?.hasFinalBoundary = true
for bodyPart in self.bodyParts {
try write(bodyPart, to: outputStream)
}
}
// MARK: - Private - Body Part Encoding
private func encode(_ bodyPart: BodyPart) throws -> Data {
var encoded = Data()
let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData()
encoded.append(initialData)
let headerData = encodeHeaders(for: bodyPart)
encoded.append(headerData)
let bodyStreamData = try encodeBodyStream(for: bodyPart)
encoded.append(bodyStreamData)
if bodyPart.hasFinalBoundary {
encoded.append(finalBoundaryData())
}
return encoded
}
private func encodeHeaders(for bodyPart: BodyPart) -> Data {
var headerText = ""
for (key, value) in bodyPart.headers {
headerText += "\(key): \(value)\(EncodingCharacters.crlf)"
}
headerText += EncodingCharacters.crlf
return headerText.data(using: String.Encoding.utf8, allowLossyConversion: false)!
}
private func encodeBodyStream(for bodyPart: BodyPart) throws -> Data {
let inputStream = bodyPart.bodyStream
inputStream.open()
defer { inputStream.close() }
var encoded = Data()
while inputStream.hasBytesAvailable {
var buffer = [UInt8](repeating: 0, count: streamBufferSize)
let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize)
if let error = inputStream.streamError {
throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: error))
}
if bytesRead > 0 {
encoded.append(buffer, count: bytesRead)
} else {
break
}
}
return encoded
}
// MARK: - Private - Writing Body Part to Output Stream
private func write(_ bodyPart: BodyPart, to outputStream: OutputStream) throws {
try writeInitialBoundaryData(for: bodyPart, to: outputStream)
try writeHeaderData(for: bodyPart, to: outputStream)
try writeBodyStream(for: bodyPart, to: outputStream)
try writeFinalBoundaryData(for: bodyPart, to: outputStream)
}
private func writeInitialBoundaryData(for bodyPart: BodyPart, to outputStream: OutputStream) throws {
let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData()
return try write(initialData, to: outputStream)
}
private func writeHeaderData(for bodyPart: BodyPart, to outputStream: OutputStream) throws {
let headerData = encodeHeaders(for: bodyPart)
return try write(headerData, to: outputStream)
}
private func writeBodyStream(for bodyPart: BodyPart, to outputStream: OutputStream) throws {
let inputStream = bodyPart.bodyStream
inputStream.open()
defer { inputStream.close() }
while inputStream.hasBytesAvailable {
var buffer = [UInt8](repeating: 0, count: streamBufferSize)
let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize)
if let streamError = inputStream.streamError {
throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: streamError))
}
if bytesRead > 0 {
if buffer.count != bytesRead {
buffer = Array(buffer[0..
/// NSDictionary *params = @{
/// kFIRParameterAchievementID : @"10_matches_won",
/// // ...
/// };
///
static NSString *const kFIRParameterAchievementID = @"achievement_id";
/// Ad Network Click ID (NSString). Used for network-specific click IDs which vary in format.
///
/// NSDictionary *params = @{
/// kFIRParameterAdNetworkClickID : @"1234567",
/// // ...
/// };
///
static NSString *const kFIRParameterAdNetworkClickID = @"aclid";
/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to
/// capture campaign information, otherwise can be populated by developer. Highly Recommended
/// (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterCampaign : @"winter_promotion",
/// // ...
/// };
///
static NSString *const kFIRParameterCampaign = @"campaign";
/// Character used in game (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterCharacter : @"beat_boss",
/// // ...
/// };
///
static NSString *const kFIRParameterCharacter = @"character";
/// Campaign content (NSString).
static NSString *const kFIRParameterContent = @"content";
/// Type of content selected (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterContentType : @"news article",
/// // ...
/// };
///
static NSString *const kFIRParameterContentType = @"content_type";
/// Coupon code for a purchasable item (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterCoupon : @"zz123",
/// // ...
/// };
///
static NSString *const kFIRParameterCoupon = @"coupon";
/// Campaign custom parameter (NSString). Used as a method of capturing custom data in a campaign.
/// Use varies by network.
///
/// NSDictionary *params = @{
/// kFIRParameterCP1 : @"custom_data",
/// // ...
/// };
///
static NSString *const kFIRParameterCP1 = @"cp1";
/// Purchase currency in 3-letter
/// ISO_4217 format (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterCurrency : @"USD",
/// // ...
/// };
///
static NSString *const kFIRParameterCurrency = @"currency";
/// Flight or Travel destination (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterDestination : @"Mountain View, CA",
/// // ...
/// };
///
static NSString *const kFIRParameterDestination = @"destination";
/// The arrival date, check-out date or rental end date for the item. This should be in
/// YYYY-MM-DD format (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterEndDate : @"2015-09-14",
/// // ...
/// };
///
static NSString *const kFIRParameterEndDate = @"end_date";
/// Flight number for travel events (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterFlightNumber : @"ZZ800",
/// // ...
/// };
///
static NSString *const kFIRParameterFlightNumber = @"flight_number";
/// Group/clan/guild ID (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterGroupID : @"g1",
/// // ...
/// };
///
static NSString *const kFIRParameterGroupID = @"group_id";
/// Item category (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterItemCategory : @"t-shirts",
/// // ...
/// };
///
static NSString *const kFIRParameterItemCategory = @"item_category";
/// Item ID (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterItemID : @"p7654",
/// // ...
/// };
///
static NSString *const kFIRParameterItemID = @"item_id";
/// The Google Place ID (NSString) that
/// corresponds to the associated item. Alternatively, you can supply your own custom Location ID.
///
/// NSDictionary *params = @{
/// kFIRParameterItemLocationID : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
/// // ...
/// };
///
static NSString *const kFIRParameterItemLocationID = @"item_location_id";
/// Item name (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterItemName : @"abc",
/// // ...
/// };
///
static NSString *const kFIRParameterItemName = @"item_name";
/// Level in game (signed 64-bit integer as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterLevel : @(42),
/// // ...
/// };
///
static NSString *const kFIRParameterLevel = @"level";
/// Location (NSString). The Google Place ID
/// that corresponds to the associated event. Alternatively, you can supply your own custom
/// Location ID.
///
/// NSDictionary *params = @{
/// kFIRParameterLocation : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
/// // ...
/// };
///
static NSString *const kFIRParameterLocation = @"location";
/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended
/// (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterMedium : @"email",
/// // ...
/// };
///
static NSString *const kFIRParameterMedium = @"medium";
/// Number of nights staying at hotel (signed 64-bit integer as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterNumberOfNights : @(3),
/// // ...
/// };
///
static NSString *const kFIRParameterNumberOfNights = @"number_of_nights";
/// Number of passengers traveling (signed 64-bit integer as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterNumberOfPassengers : @(11),
/// // ...
/// };
///
static NSString *const kFIRParameterNumberOfPassengers = @"number_of_passengers";
/// Number of rooms for travel events (signed 64-bit integer as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterNumberOfRooms : @(2),
/// // ...
/// };
///
static NSString *const kFIRParameterNumberOfRooms = @"number_of_rooms";
/// Flight or Travel origin (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterOrigin : @"Mountain View, CA",
/// // ...
/// };
///
static NSString *const kFIRParameterOrigin = @"origin";
/// Purchase price (double as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterPrice : @(1.0),
/// kFIRParameterCurrency : @"USD", // e.g. $1.00 USD
/// // ...
/// };
///
static NSString *const kFIRParameterPrice = @"price";
/// Purchase quantity (signed 64-bit integer as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterQuantity : @(1),
/// // ...
/// };
///
static NSString *const kFIRParameterQuantity = @"quantity";
/// Score in game (signed 64-bit integer as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterScore : @(4200),
/// // ...
/// };
///
static NSString *const kFIRParameterScore = @"score";
/// The search string/keywords used (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterSearchTerm : @"periodic table",
/// // ...
/// };
///
static NSString *const kFIRParameterSearchTerm = @"search_term";
/// Shipping cost (double as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterShipping : @(9.50),
/// kFIRParameterCurrency : @"USD", // e.g. $9.50 USD
/// // ...
/// };
///
static NSString *const kFIRParameterShipping = @"shipping";
/// Sign up method (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterSignUpMethod : @"google",
/// // ...
/// };
///
static NSString *const kFIRParameterSignUpMethod = @"sign_up_method";
/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban
/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your
/// property. Highly recommended (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterSource : @"InMobi",
/// // ...
/// };
///
static NSString *const kFIRParameterSource = @"source";
/// The departure date, check-in date or rental start date for the item. This should be in
/// YYYY-MM-DD format (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterStartDate : @"2015-09-14",
/// // ...
/// };
///
static NSString *const kFIRParameterStartDate = @"start_date";
/// Tax amount (double as NSNumber).
///
/// NSDictionary *params = @{
/// kFIRParameterTax : @(1.0),
/// kFIRParameterCurrency : @"USD", // e.g. $1.00 USD
/// // ...
/// };
///
static NSString *const kFIRParameterTax = @"tax";
/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword
/// (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterTerm : @"game",
/// // ...
/// };
///
static NSString *const kFIRParameterTerm = @"term";
/// A single ID for a ecommerce group transaction (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterTransactionID : @"ab7236dd9823",
/// // ...
/// };
///
static NSString *const kFIRParameterTransactionID = @"transaction_id";
/// Travel class (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterTravelClass : @"business",
/// // ...
/// };
///
static NSString *const kFIRParameterTravelClass = @"travel_class";
/// A context-specific numeric value which is accumulated automatically for each event type. This is
/// a general purpose parameter that is useful for accumulating a key metric that pertains to an
/// event. Examples include revenue, distance, time and points. Value should be specified as signed
/// 64-bit integer or double as NSNumber. Notes: Values for pre-defined currency-related events
/// (such as @c kFIREventAddToCart) should be supplied using double as NSNumber and must be
/// accompanied by a @c kFIRParameterCurrency parameter. The valid range of accumulated values is
/// [-9,223,372,036,854.77, 9,223,372,036,854.77].
///
/// NSDictionary *params = @{
/// kFIRParameterValue : @(3.99),
/// kFIRParameterCurrency : @"USD", // e.g. $3.99 USD
/// // ...
/// };
///
static NSString *const kFIRParameterValue = @"value";
/// Name of virtual currency type (NSString).
///
/// NSDictionary *params = @{
/// kFIRParameterVirtualCurrencyName : @"virtual_currency_name",
/// // ...
/// };
///
static NSString *const kFIRParameterVirtualCurrencyName = @"virtual_currency_name";
================================================
FILE: iOS/Manager/EZShopManager/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h
================================================
/// @file FIRUserPropertyNames.h
///
/// Predefined user property names.
///
/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can
/// later analyze different behaviors of various segments of your userbase. You may supply up to 25
/// unique UserProperties per app, and you can use the name and value of your choosing for each one.
/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and
/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to
/// 36 characters long. The "firebase_" prefix is reserved and should not be used.
/// The method used to sign in. For example, "google", "facebook" or "twitter".
static NSString *const kFIRUserPropertySignUpMethod = @"sign_up_method";
================================================
FILE: iOS/Manager/EZShopManager/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h
================================================
#import "FIRAnalyticsConfiguration.h"
#import "FIRApp.h"
#import "FIRConfiguration.h"
#import "FIROptions.h"
#import "FIRAnalytics+AppDelegate.h"
#import "FIRAnalytics.h"
#import "FIREventNames.h"
#import "FIRParameterNames.h"
#import "FIRUserPropertyNames.h"
================================================
FILE: iOS/Manager/EZShopManager/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap
================================================
framework module FirebaseAnalytics {
umbrella header "FirebaseAnalytics.h"
export *
module * { export *}
link "sqlite3"
link "z"
link framework "CoreGraphics"
link framework "Foundation"
link framework "UIKit"
}
================================================
FILE: iOS/Manager/EZShopManager/Pods/FirebaseCore/Frameworks/FirebaseCore.framework/Headers/FIRAnalyticsConfiguration.h
================================================
#import %@%@%@%@%@ %@\n";
[outputHTML appendFormat:fmt, responseDataLength, responseMIMEType,
responseDataFileName, [responseDataFileName pathExtension]];
}
} else {
// The response data was not an image; just show the length and MIME type
[outputHTML appendFormat:@" data: %lld bytes, %@\n",
responseDataLength, responseMIMEType ? responseMIMEType : @"(no response type)"];
}
// Make a single string of the request and response, suitable for copying
// to the clipboard and pasting into a bug report
NSMutableString *copyable = [NSMutableString string];
if (comment) {
[copyable appendFormat:@"%@\n\n", comment];
}
[copyable appendFormat:@"%@ elapsed: %5.3fsec\n", now, elapsed];
if (redirectedFromURLString) {
[copyable appendFormat:@"Redirected from %@\n", redirectedFromURLString];
}
[copyable appendFormat:@"Request: %@ %@\n", requestMethod, requestURL];
if (requestHeaders.count > 0) {
[copyable appendFormat:@"Request headers:\n%@\n",
[[self class] headersStringForDictionary:requestHeaders]];
}
if (bodyDataLength > 0) {
[copyable appendFormat:@"Request body: (%llu bytes)\n", bodyDataLength];
if (bodyDataStr) {
[copyable appendFormat:@"%@\n", bodyDataStr];
}
[copyable appendString:@"\n"];
}
if (response) {
[copyable appendFormat:@"Response: status %d\n", (int) status];
[copyable appendFormat:@"Response headers:\n%@\n",
[[self class] headersStringForDictionary:responseHeaders]];
[copyable appendFormat:@"Response body: (%lld bytes)\n", responseDataLength];
if (responseDataLength > 0) {
NSString *logResponseBody = self.logResponseBody;
if (logResponseBody) {
// The user has provided the response body text.
responseDataStr = [logResponseBody copy];
self.logResponseBody = nil;
}
if (responseDataStr != nil) {
[copyable appendFormat:@"%@\n", responseDataStr];
} else {
// Even though it's redundant, we'll put in text to indicate that all the bytes are binary.
if (self.destinationFileURL) {
[copyable appendFormat:@"<<%lld bytes>> to file %@\n",
responseDataLength, self.destinationFileURL.path];
} else {
[copyable appendFormat:@"<<%lld bytes>>\n", responseDataLength];
}
}
}
}
if (error) {
[copyable appendFormat:@"Error: %@\n", error];
}
// Save to log property before adding the separator
self.log = copyable;
[copyable appendString:@"-----------------------------------------------------------\n"];
// Write the copyable version to another file (linked to at the top of the html file, above)
//
// Ideally, something to just copy this to the clipboard like
// Copy here."
// would work everywhere, but it only works in Safari as of 8/2010
if (gIsLoggingToFile) {
NSString *parentDir = [[self class] loggingDirectory];
NSString *copyablePath = [logDirectory stringByAppendingPathComponent:copyableFileName];
NSError *copyableError = nil;
if (![copyable writeToFile:copyablePath
atomically:NO
encoding:NSUTF8StringEncoding
error:©ableError]) {
// Error writing to file
NSLog(@"%@ logging write error:%@ (%@)", [self class], copyableError, copyablePath);
}
[outputHTML appendString:@""];
// Append the HTML to the main output file
const char* htmlBytes = outputHTML.UTF8String;
NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:htmlPath
append:YES];
[stream open];
[stream write:(const uint8_t *) htmlBytes maxLength:strlen(htmlBytes)];
[stream close];
// Make a symlink to the latest html
NSString *const symlinkNameSuffix = [[self class] symlinkNameSuffix];
NSString *symlinkName = [processName stringByAppendingString:symlinkNameSuffix];
NSString *symlinkPath = [parentDir stringByAppendingPathComponent:symlinkName];
[fileMgr removeItemAtPath:symlinkPath error:NULL];
[fileMgr createSymbolicLinkAtPath:symlinkPath
withDestinationPath:htmlPath
error:NULL];
#if TARGET_OS_IPHONE
static BOOL gReportedLoggingPath = NO;
if (!gReportedLoggingPath) {
gReportedLoggingPath = YES;
NSLog(@"GTMSessionFetcher logging to \"%@\"", parentDir);
}
#endif
}
}
- (NSInputStream *)loggedInputStreamForInputStream:(NSInputStream *)inputStream {
if (!inputStream) return nil;
if (![GTMSessionFetcher isLoggingEnabled]) return inputStream;
[self clearLoggedStreamData]; // Clear any previous data.
Class monitorClass = NSClassFromString(@"GTMReadMonitorInputStream");
if (!monitorClass) {
NSString const *str = @"<