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
2 changes: 1 addition & 1 deletion .swiftformat
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SwiftFormat configuration for IONCameraLib
# Targets iOS 14+ / Swift 5.9+
# Targets iOS 15+ / Swift 5.9+

--swiftversion 5.9
--minversion 0.54.0
Expand Down
2 changes: 1 addition & 1 deletion IONCameraLib.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Pod::Spec.new do |spec|
spec.license = { :type => package['license'], :file => "LICENSE" }
spec.author = { package['author'] => package['email'] }

spec.ios.deployment_target = "14.0"
spec.ios.deployment_target = "15.0"

spec.source = { :git => package['repository']['url'], :tag => "#{spec.version}" }
spec.source_files = "Sources/IONCameraLib/**/*.swift"
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PackageDescription
let package = Package(
name: "IONCameraLib",
platforms: [
.iOS(.v14),
.iOS(.v15),
],
products: [
.library(
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ The library includes a `PrivacyInfo.xcprivacy` file that documents the required

## Requirements

- iOS 14.0+
- iOS 15.0+
- Xcode 15.0+
- Swift 5.0+

Expand Down
21 changes: 5 additions & 16 deletions Sources/IONCameraLib/Interfaces/IONCAMRMediaResultGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,15 @@ private enum IONCAMRMetadataError: Error {

final class IONCAMRMediaResultGenerator: IONCAMRMetadataGetterDelegate {
func getVideoMetadata(from url: URL) async throws -> IONCAMRMetadata {
let asset = AVAsset(url: url)
let asset = AVURLAsset(url: url)

let durationProperty: CMTime
let trackArray: [AVAssetTrack]
if #available(iOS 15, *) {
durationProperty = try await asset.load(.duration)
trackArray = try await asset.loadTracks(withMediaType: .video)
} else {
durationProperty = asset.duration
trackArray = asset.tracks(withMediaType: .video)
}
let durationProperty = try await asset.load(.duration)
let trackArray = try await asset.loadTracks(withMediaType: .video)

guard let track = trackArray.first else { throw IONCAMRMetadataError.noVideoTrack }
guard let urlMetadata = url.metadata else { throw IONCAMRMetadataError.urlConversionError }

let naturalSize: CGSize = if #available(iOS 15, *) {
try await track.load(.naturalSize)
} else {
track.naturalSize
}
let naturalSize = try await track.load(.naturalSize)
let duration = Int(CMTimeGetSeconds(durationProperty).rounded())
let format = url.pathExtension.lowercased()
let creationDate = urlMetadata.date
Expand All @@ -53,7 +42,7 @@ final class IONCAMRMediaResultGenerator: IONCAMRMetadataGetterDelegate {
extension IONCAMRMediaResultGenerator: IONCAMRThumbnailGeneratorDelegate {
func getImage(from videoURL: URL, _ completion: @escaping (UIImage?) -> Void) {
DispatchQueue.global().async { // run this on background
let asset = AVAsset(url: videoURL)
let asset = AVURLAsset(url: videoURL)
let avAssetImageGenerator = AVAssetImageGenerator(asset: asset)
avAssetImageGenerator.appliesPreferredTrackTransform = true // correct thumbnail orientation
let thumnailTime = CMTimeMake(value: 2, timescale: 1) // time of the video to be used as a thumbnail
Expand Down
27 changes: 13 additions & 14 deletions Sources/IONCameraLib/Interfaces/IONCAMRPlayerBehaviour.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,27 @@ final class IONCAMRPlayerBehaviour: NSObject, IONCAMRPlayerDelegate {
func playVideo(_ url: URL) async throws {
// Resolve the URL in case the app sandbox path has changed
let resolvedURL = try resolveVideoURL(url)
let asset = AVAsset(url: resolvedURL)
let asset = AVURLAsset(url: resolvedURL)

let isPlayable: Bool = if #available(iOS 15, *) {
try await asset.load(.isPlayable)
} else {
asset.isPlayable
}
let isPlayable = try await asset.load(.isPlayable)

if isPlayable {
DispatchQueue.main.async {
let player = AVPlayer(url: resolvedURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.coordinator.present(playerViewController)

player.play()
}
await presentPlayer(for: resolvedURL)
} else {
throw IONCAMRError.playVideoIssue
}
}

@MainActor
private func presentPlayer(for url: URL) {
let player = AVPlayer(url: url)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
coordinator.present(playerViewController)

player.play()
}

private func resolveVideoURL(_ url: URL) throws -> URL {
// Check if the file exists at the given URL
if FileManager.default.fileExists(atPath: url.path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct IONCAMRPhotoThumbnailView: View {
}
}
// We need to use the task to work on a concurrent request to load the image from the photo library service, which is asynchronous work.
.taskOperation {
.task(priority: .userInitiated) {
await loadImageAsset()
}
// Finally, when the view disappears, we need to free it up from the memory
Expand All @@ -82,22 +82,3 @@ extension IONCAMRPhotoThumbnailView {
image = Image(uiImage: uiImage)
}
}

extension View {
func taskOperation(priority: TaskPriority = .userInitiated, _ action: @escaping @Sendable () async -> Void) -> some View {
if #available(iOS 15, *) {
return task(priority: priority, action)
} else {
return taskiOS14(priority: priority, action)
}
}

@available(iOS, deprecated: 15.0, message: "This extension is no longer necessary. Use API built into SDK")
func taskiOS14(priority: TaskPriority = .userInitiated, _ action: @escaping @Sendable () async -> Void) -> some View {
onAppear {
Task(priority: priority) {
await action()
}
}
}
}
Loading