Skip to content

Commit

Permalink
Releases/v0.6.0 (#97)
Browse files Browse the repository at this point in the history
* Remove UIKit dependency (#90)

* Replace use of UIDevice and use a different non-UIKit source

* Version updates (#91)

* docs: backfill missing inline API docs (#92)

* feat: Foundation Measurement API for chunk size (#94)

* refactor:  Respell Version to SemanticVersion for explicitness in API (#95)

* Rename revision to patch as in SemVer 2.0.0

* Rename Version to SemanticVersion for explicitness

* Inline API docs and adjust indentation to match rest of the package

* Lowercase to avoid casing issues (#98)
  • Loading branch information
andrewjl-mux authored Aug 24, 2023
1 parent 4dd9c5a commit b1abb90
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 79 deletions.
2 changes: 1 addition & 1 deletion Mux-Upload-SDK.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = 'Mux-Upload-SDK'
s.module_name = 'MuxUploadSDK'
s.version = '0.3.1'
s.version = '0.6.0'
s.summary = 'Upload video to Mux.'
s.description = 'A library for uploading video to Mux. Similar to UpChunk, but for iOS.'

Expand Down
75 changes: 55 additions & 20 deletions Sources/MuxUploadSDK/InternalUtilities/Reporting/Reporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,36 @@
//

import Foundation
import UIKit

fileprivate func processInfoOperationSystemVersion() -> String {
let version = ProcessInfo().operatingSystemVersion
return "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"
}

fileprivate func posixModelName() -> String {
var systemName = utsname()
uname(&systemName)
return withUnsafePointer(to: &systemName.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
} ?? "Unknown"
}

fileprivate func inferredPlatformName() -> String {
let modelName = posixModelName().lowercased()
if modelName.contains("ipad") {
return "iPadOS"
} else if modelName.contains("iphone") {
return "iOS"
} else {
#if targetEnvironment(simulator)
return "Simulator"
#else
return "Unknown"
#endif
}
}

class Reporter: NSObject {

Expand All @@ -28,9 +57,11 @@ class Reporter: NSObject {
var locale: Locale {
Locale.current
}
var device: UIDevice {
UIDevice.current
}

let model: String
let platformName: String
let platformVersion: String

var regionCode: String? {
if #available(iOS 16, *) {
return locale.language.region?.identifier
Expand All @@ -52,6 +83,10 @@ class Reporter: NSObject {
string: "https://mobile.muxanalytics.com"
)!

self.model = posixModelName()
self.platformName = inferredPlatformName()
self.platformVersion = processInfoOperationSystemVersion()

super.init()

let sessionConfig: URLSessionConfiguration = URLSessionConfiguration.default
Expand Down Expand Up @@ -105,14 +140,14 @@ extension Reporter {
let data = UploadSucceededEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
inputDuration: inputDuration,
inputSize: inputSize,
inputStandardizationRequested: options.inputStandardization.isRequested,
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
uploadStartTime: uploadStartTime,
uploadEndTime: uploadEndTime,
uploadURL: uploadURL
Expand Down Expand Up @@ -145,15 +180,15 @@ extension Reporter {
let data = UploadFailedEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
errorDescription: errorDescription,
inputDuration: inputDuration,
inputSize: inputSize,
inputStandardizationRequested: options.inputStandardization.isRequested,
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
uploadStartTime: uploadStartTime,
uploadEndTime: uploadEndTime,
uploadURL: url
Expand Down Expand Up @@ -186,15 +221,15 @@ extension Reporter {
let data = InputStandardizationSucceededEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
inputDuration: inputDuration,
inputSize: inputSize,
maximumResolution: options.inputStandardization.maximumResolution.description,
nonStandardInputReasons: nonStandardInputReasons.map(\.description),
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
standardizationStartTime: standardizationStartTime,
standardizationEndTime: standardizationEndTime,
uploadURL: uploadURL
Expand Down Expand Up @@ -229,16 +264,16 @@ extension Reporter {
let data = InputStandardizationFailedEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
errorDescription: errorDescription,
inputDuration: inputDuration,
inputSize: inputSize,
maximumResolution: options.inputStandardization.maximumResolution.description,
nonStandardInputReasons: nonStandardInputReasons.map(\.description),
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
standardizationStartTime: standardizationStartTime,
standardizationEndTime: standardizationEndTime,
uploadCanceled: uploadCanceled,
Expand Down
5 changes: 5 additions & 0 deletions Sources/MuxUploadSDK/PublicAPI/DirectUpload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import AVFoundation
import Foundation

/// Indicates whether a finished upload failed due to an error
/// or succeeded along with details
public typealias DirectUploadResult = Result<DirectUpload.SuccessDetails, DirectUploadError>

///
Expand Down Expand Up @@ -341,6 +343,9 @@ public final class DirectUpload {
*/
public var progressHandler: StateHandler?

/**
Details about a ``DirectUpload`` after it successfully finished
*/
public struct SuccessDetails : Sendable, Hashable {
public let finalState: TransportStatus
}
Expand Down
143 changes: 105 additions & 38 deletions Sources/MuxUploadSDK/PublicAPI/Options/DirectUploadOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,65 @@

import Foundation

// MARK: - Direct Upload Options

/// Options for the direct upload
public struct DirectUploadOptions {

// MARK: - Transport Options

/// Options to control the SDK network operations to
/// transport the direct upload input to Mux
/// Options for tuning network transport of direct upload
/// chunks to Mux. Using the ``default`` is recommended
/// for most applications.
public struct Transport {

/// At least 8M is recommended
/// The size of each file chunk in bytes sent by the
/// SDK during an upload. At least 8MB is recommended.
public var chunkSizeInBytes: Int

/// Number of retry attempts per chunk if the
/// associated request fails
/// Number of retry attempts per chunk if its upload
/// request is unsuccessful
public var retryLimitPerChunk: Int

/// A default set of transport options: 8MB chunk
/// size and chunk request retry limit of 3
/// Default options for ``DirectUpload`` chunk transport
/// over the network. The chunk size is 8MB and the
/// per-chunk retry limit is 3.
public static var `default`: Transport {
Transport(
chunkSizeInBytes: 8 * 1024 * 1024,
retryLimitPerChunk: 3
)
}

/// Initializes options that govern network transport
/// by the SDK
///
/// Initializes options for transport of upload chunks
/// over the network
/// - Parameters:
/// - chunkSize: the size of each file chunk in
/// bytes the SDK sends when uploading, default
/// value is 8MB
/// - retriesPerChunk: number of retry attempts
/// if the chunk request fails, default value is 3
/// - chunkSize: the size of each file chunk sent
/// by the SDK during an upload.
/// Defaults to 8MB.
/// - retryLimitPerChunk: number of times a failed
/// chunk request is retried. Default limit is
/// 3 retries.
public init(
chunkSize: Measurement<UnitInformationStorage> = .defaultDirectUploadChunkSize,
retryLimitPerChunk: Int = 3
) {
self.chunkSizeInBytes = Int(
abs(chunkSize.converted(to: .bytes).value)
.rounded(.down)
)
self.retryLimitPerChunk = retryLimitPerChunk
}

/// Initializes options for transport of upload chunks
/// over the network
/// - Parameters:
/// - chunkSizeInBytes: the size of each file
/// chunk in bytes the SDK uploads in a single
/// request. Default chunk size is 8MB.
/// - retryLimitPerChunk: number of times a failed
/// chunk request is retried. Default limit is
/// 3 retries.
public init(
chunkSizeInBytes: Int = 8 * 1024 * 1024,
retryLimitPerChunk: Int = 3
Expand All @@ -47,12 +72,14 @@ public struct DirectUploadOptions {
}
}

/// Transport options for the direct upload
/// Network transport options for direct upload chunks
public var transport: Transport

// MARK: - Input Standardization Options

/// Options controlling direct upload input standardization
/// Options for adjusments made by ``DirectUpload``
/// to some inputs to minimize processing time during
/// ingestion
public struct InputStandardization {

/// If requested the SDK will attempt to detect
Expand Down Expand Up @@ -124,8 +151,8 @@ public struct DirectUploadOptions {
maximumResolution: .default
)

// Kept private to an invalid combination of parameters
// being used for initialization
// Kept private to avoid an invalid combination of
// parameters being used for initialization
private init(
isRequested: Bool,
maximumResolution: MaximumResolution
Expand All @@ -134,10 +161,8 @@ public struct DirectUploadOptions {
self.maximumResolution = maximumResolution
}

/// Used to initialize ``DirectUploadOptions.InputStandardization``
/// with that enables input standardization with
/// a maximum resolution
///
/// Initializes options that request input
/// standardization with a custom maximum resolution
/// - Parameters:
/// - maximumResolution: the maximum resolution
/// of the standardized input
Expand Down Expand Up @@ -186,12 +211,14 @@ public struct DirectUploadOptions {

// MARK: Direct Upload Options Initializers

/// Initializes options that dictate how the direct upload
/// is carried out by the SDK
/// - Parameters:
/// - inputStandardization: options to enable or
/// disable standardizing the format of the direct
/// upload inputs, it is requested by default. To
/// prevent the SDK from making any changes to the
/// format of the input use ``DirectUploadOptions.InputStandardization.skipped``
/// - inputStandardization: options related to input
/// standardization. Input standardization is requested
/// by default.
/// To skip input standardization pass in
/// ``DirectUploadOptions.InputStandardization.skipped``.
/// - transport: options for transporting the
/// direct upload input to Mux
/// - eventTracking: event tracking options for the
Expand All @@ -206,19 +233,49 @@ public struct DirectUploadOptions {
self.eventTracking = eventTracking
}

/// Initializes options that dictate how the direct upload
/// is carried out by the SDK
/// - Parameters:
/// - eventTracking: event tracking options for the
/// direct upload
/// - inputStandardization: options related to input
/// standardization. Input standardization is requested
/// by default.
/// To skip input standardization pass in
/// ``DirectUploadOptions.InputStandardization.skipped``.
/// - chunkSize: The size of each file chunk sent by
/// the SDK during an upload. Defaults to 8MB.
/// - retryLimitPerChunk: number of retry attempts
/// if the chunk request fails. Defaults to 3.
public init(
eventTracking: EventTracking = .default,
inputStandardization: InputStandardization = .default,
chunkSize: Measurement<UnitInformationStorage> = .defaultDirectUploadChunkSize,
retryLimitPerChunk: Int = 3
) {
self.eventTracking = eventTracking
self.inputStandardization = inputStandardization
self.transport = Transport(
chunkSize: chunkSize,
retryLimitPerChunk: retryLimitPerChunk
)
}

/// Initializes options that dictate how the direct upload
/// is carried out by the SDK
/// - Parameters:
/// - eventTracking: event tracking options for the
/// direct upload
/// - inputStandardization: options to enable or
/// disable standardizing the format of the direct
/// upload inputs, it is requested by default. To
/// prevent the SDK from making any changes to the
/// format of the input use ``DirectUploadOptions.InputStandardization.skipped``
/// - chunkSize: the size of each file chunk in
/// bytes the SDK sends when uploading, default
/// value is 8MB
/// - retriesPerChunk: number of retry attempts
/// if the chunk request fails, default value is 3
/// - inputStandardization: options related to input
/// standardization. Input standardization is requested
/// by default.
/// To skip input standardization pass in
/// ``DirectUploadOptions.InputStandardization.skipped``.
/// - chunkSizeInBytes: The size of each file chunk
/// in bytes sent by the SDK during an upload.
/// Defaults to 8MB.
/// - retryLimitPerChunk: number of retry attempts
/// if the chunk request fails. Defaults to 3.
public init(
eventTracking: EventTracking = .default,
inputStandardization: InputStandardization = .default,
Expand All @@ -237,6 +294,16 @@ public struct DirectUploadOptions {

// MARK: - Extensions

extension Measurement where UnitType == UnitInformationStorage {
/// Default direct upload chunk size
public static var defaultDirectUploadChunkSize: Self {
Measurement(
value: 8,
unit: .megabytes
)
}
}

extension DirectUploadOptions.InputStandardization.MaximumResolution: CustomStringConvertible {
public var description: String {
switch self {
Expand Down
Loading

0 comments on commit b1abb90

Please sign in to comment.