Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ jobs:
lint:
name: SwiftLint
runs-on: macOS-latest

steps:
- name: Checkout
uses: actions/checkout@v5
- name: SwiftLint

- name: Install SwiftLint
run: |
if ! command -v swiftlint &> /dev/null; then
brew install swiftlint
fi
swiftlint --strict
fi

- name: SwiftLint
run: swiftlint --strict

validate-podspec:
name: Validate Podspec
Expand Down
60 changes: 60 additions & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# SwiftFormat configuration for IONCameraLib
# Targets iOS 14+ / Swift 5.9+

--swiftversion 5.9
--minversion 0.54.0

# Indentation
--indent 4
--tabwidth 4
--smarttabs enabled
--indentcase false

# Line endings
--linebreaks lf

# Headers
--header strip

# Line length — matches SwiftLint warning threshold
--maxwidth 150
--wraparguments before-first
--wrapparameters before-first
--wrapcollections before-first
--closingparen balanced
--wrapreturntype if-multiline

# Imports
--importgrouping testable-last

# Self — remove redundant self outside init/deinit
--self init-only

# Trailing items
--semicolons never
--commas always
--trimwhitespace always

# Attributes
--funcattributes prev-line
--typeattributes prev-line
--varattributes same-line

# Closures & functions
--trailingclosures always
--nospaceoperators ..<,...
--operatorfunc spaced

# Braces
--guardelse auto

# Redundant syntax
--redundanttype inferred
--stripunusedargs closure-only
--patternlet inline

# Organise declarations (protocols, extensions, types)
--extensionacl on-declarations

# Disable rules that conflict with SwiftLint opt-in rules
--disable blankLinesAtStartOfScope
79 changes: 53 additions & 26 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,61 @@
included:
- Sources
- Tests

disabled_rules:
- trailing_whitespace
- switch_case_alignment
- trailing_whitespace # handled by SwiftFormat
- line_length # handled by SwiftFormat --maxwidth

opt_in_rules:
- empty_count
- empty_string
excluded:
- Carthage
- Pods
- vendor
- SwiftLint/Common/3rdPartyLib
# Code quality
- empty_count
- empty_string
- explicit_init
- first_where
- contains_over_filter_count
- unavailable_function
- force_unwrapping
- implicitly_unwrapped_optional
- redundant_nil_coalescing
- prefer_self_type_over_type_of_self
# Formatting & style
- closure_end_indentation
- closure_spacing
- collection_alignment
- literal_expression_end_indentation
- multiline_arguments
- multiline_parameters
- operator_usage_whitespace
- sorted_imports
- unneeded_parentheses_in_closure_argument
- vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces

# Severity overrides
force_cast: warning
force_try: warning

line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
warning: 40
error: 60
function_parameter_count:
warning: 6
error: 8
warning: 6
error: 8
ignores_default_parameters: true
type_body_length:
warning: 300
error: 500
warning: 200
error: 300
file_length:
warning: 1000
error: 1500
ignore_comment_only_lines: true
warning: 400
error: 600
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 25
reporter: "xcode"
warning: 10
error: 15
reporter: "xcode"
9 changes: 5 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// swift-tools-version: 5.7
// swift-tools-version: 5.9
import PackageDescription

let package = Package(
name: "IONCameraLib",
platforms: [
.iOS(.v14)
.iOS(.v14),
],
products: [
.library(
name: "IONCameraLib",
targets: ["IONCameraLib"]),
targets: ["IONCameraLib"]
),
],
dependencies: [
.package(url: "https://github.com/Quick/Nimble.git", from: "13.0.0"),
.package(url: "https://github.com/Quick/Nimble.git", from: "13.0.0"),
.package(url: "https://github.com/Quick/Quick.git", from: "7.0.0"),
],
targets: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ extension IONCAMRFlowResultsHandler {
switch result {
case .success(let value):
if let mediaResult = value as? IONCAMRMediaResult {
self.responseDelegate?.callback(result: mediaResult)
responseDelegate?.callback(result: mediaResult)
} else if let mediaArray = value as? [IONCAMRMediaResult] {
self.responseDelegate?.callback(result: mediaArray)
responseDelegate?.callback(result: mediaArray)
}
case .failure(let error):
self.responseDelegate?.callback(error: error)
responseDelegate?.callback(error: error)
}
}

func didCancel(_ error: IONCAMRError) {
self.responseDelegate?.callback(error: error)
responseDelegate?.callback(error: error)
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import Photos
import UniformTypeIdentifiers
import UIKit
import UniformTypeIdentifiers

/// Contains all method that converts `IONCAMRMediaOptions` properties into a native SDK equivalent
extension IONCAMRMediaOptions {
/// Converts the `direction` property into a `UIImagePickerController.CameraDevice`.
/// - Returns: The resulting equivalent
var cameraDevice: UIImagePickerController.CameraDevice {
switch self.direction {
case .front: return .front
case .back: return .rear
switch direction {
case .front: .front
case .back: .rear
}
}
}

extension IONCAMRMediaType: Hashable {
var stringArray: [String] {
self.transform(basedOn: [IONCAMRMediaType.picture: UTType.image, .video: .movie])
transform(basedOn: [IONCAMRMediaType.picture: UTType.image, .video: .movie])
.map(\.identifier)
}

var phAssetArray: [PHAssetMediaType] {
self.transform(basedOn: [IONCAMRMediaType.picture: PHAssetMediaType.image, .video: .video])
transform(basedOn: [IONCAMRMediaType.picture: PHAssetMediaType.image, .video: .video])
}

private func transform<T>(basedOn map: [Self: T]) -> [T] {
Expand Down
33 changes: 18 additions & 15 deletions Sources/IONCameraLib/Extensions/UIImage+MediaOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,36 @@ extension UIImage {
func toData(with options: IONCAMRTakePhotoOptions? = nil) -> Data? {
let data: Data?

if let options = options, options.encodingType == .jpeg {
if let options, options.encodingType == .jpeg {
let quality = !options.allowEdit && !options.correctOrientation && options.quality == 100 ? 1.0 : CGFloat(options.quality) / 100
data = self.jpegData(compressionQuality: quality)
data = jpegData(compressionQuality: quality)
} else {
data = self.pngData()
data = pngData()
}

return data
}

/// Provides a couple of transformations (rotation and resize) to the `UIImage` object, based on the user defined options.
/// - Parameter options: User defined options containing the transformations (if any) to apply.
/// - Returns: The resulting image. It returns `nil` if some issue occured.
func fix(with options: IONCAMRTakePhotoOptions) -> UIImage? {
var image = self

if options.correctOrientation, let orientedImage = image.fixOrientation() {
image = orientedImage
}
if let targetSize = options.size, let resizedImage = image.resizeTo(CGSize(size: targetSize)) {
image = resizedImage
}

return image
}

private func applyConfigurations(_ resolution: CGFloat, and quality: CGFloat) -> String? {
var image = self
let minimumSide = resolution

var newSize: CGSize?
if image.size.height > image.size.width {
if image.size.width > minimumSide {
Expand All @@ -48,34 +48,37 @@ extension UIImage {
let ratio = image.size.width / image.size.height
newSize = .init(width: minimumSide * ratio, height: minimumSide)
}
if let newSize = newSize, let resizedImage = image.resizeTo(newSize) {

if let newSize, let resizedImage = image.resizeTo(newSize) {
image = resizedImage
}
return image.jpegData(compressionQuality: quality)?.base64EncodedString()
}
}

// MARK: - IONCAMRRecordVideoOptions extension

extension UIImage {
func pictureThumbnailData(
with originalResolution: IONCAMRSize? = nil,
and originalQuality: Int = IONCAMRTakePhotoOptions.ThumbnailDefaultConfigurations.quality
) -> String? {
guard let originalResolution = originalResolution ?? (try? .initSquare(with: IONCAMRTakePhotoOptions.ThumbnailDefaultConfigurations.resolution))
)
-> String? {
guard let originalResolution = originalResolution ??
(try? .initSquare(with: IONCAMRTakePhotoOptions.ThumbnailDefaultConfigurations.resolution))
else { return nil }
let resolution = CGFloat(
min(originalResolution.height, originalResolution.width, IONCAMRTakePhotoOptions.ThumbnailDefaultConfigurations.resolution)
)
let quality = CGFloat(originalQuality / 100)

return self.applyConfigurations(resolution, and: quality)
return applyConfigurations(resolution, and: quality)
}

var defaultVideoThumbnailData: String? {
let resolution = CGFloat(IONCAMRRecordVideoOptions.ThumbnailDefaultConfigurations.resolution)
let quality = CGFloat(IONCAMRRecordVideoOptions.ThumbnailDefaultConfigurations.quality)

return self.applyConfigurations(resolution, and: quality)
return applyConfigurations(resolution, and: quality)
}
}
Loading
Loading