diff --git a/Examples/MonoImage/MonoImage.xcodeproj/project.pbxproj b/Examples/MonoImage/MonoImage.xcodeproj/project.pbxproj index 692b245..9e725da 100644 --- a/Examples/MonoImage/MonoImage.xcodeproj/project.pbxproj +++ b/Examples/MonoImage/MonoImage.xcodeproj/project.pbxproj @@ -146,7 +146,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0820; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "eje Inc."; TargetAttributes = { BFB8923F1E2F9CFF00FA9129 = { @@ -157,7 +157,7 @@ }; buildConfigurationList = BFB8923B1E2F9CFF00FA9129 /* Build configuration list for PBXProject "MonoImage" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -242,6 +242,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -251,6 +252,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -258,6 +260,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -296,6 +299,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -305,6 +309,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -312,6 +317,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -350,7 +356,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.MonoImage"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -366,7 +372,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.MonoImage"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Examples/MonoImage/Sources/AppDelegate.swift b/Examples/MonoImage/Sources/AppDelegate.swift index b5ec7ae..9f2b1cf 100644 --- a/Examples/MonoImage/Sources/AppDelegate.swift +++ b/Examples/MonoImage/Sources/AppDelegate.swift @@ -11,8 +11,8 @@ import UIKit @UIApplicationMain final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = ViewController() window?.makeKeyAndVisible() diff --git a/Examples/MonoImage/Sources/ViewController.swift b/Examples/MonoImage/Sources/ViewController.swift index 0607e91..b81a7e2 100644 --- a/Examples/MonoImage/Sources/ViewController.swift +++ b/Examples/MonoImage/Sources/ViewController.swift @@ -40,7 +40,7 @@ final class ViewController: UIViewController { NSLayoutConstraint.activate(constraints) // double tap to reset rotation - let doubleTapGestureRecognizer = UITapGestureRecognizer(target: panoramaView, action: #selector(PanoramaView.setNeedsResetRotation(_:))) + let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(resetRotation)) doubleTapGestureRecognizer.numberOfTapsRequired = 2 panoramaView.addGestureRecognizer(doubleTapGestureRecognizer) @@ -64,4 +64,8 @@ final class ViewController: UIViewController { panoramaView?.updateInterfaceOrientation(with: coordinator) } + + @objc func resetRotation() { + panoramaView?.setNeedsResetRotation() + } } diff --git a/Examples/MonoVideo/MonoVideo.xcodeproj/project.pbxproj b/Examples/MonoVideo/MonoVideo.xcodeproj/project.pbxproj index 7e1e1aa..eb1bb09 100644 --- a/Examples/MonoVideo/MonoVideo.xcodeproj/project.pbxproj +++ b/Examples/MonoVideo/MonoVideo.xcodeproj/project.pbxproj @@ -149,7 +149,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0820; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "eje Inc."; TargetAttributes = { BFA89A981E3117C0005A3529 = { @@ -160,7 +160,7 @@ }; buildConfigurationList = BFA89A941E3117C0005A3529 /* Build configuration list for PBXProject "MonoVideo" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -246,6 +246,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -255,6 +256,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -262,6 +264,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -300,6 +303,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -309,6 +313,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -316,6 +321,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -354,7 +360,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.MonoVideo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -370,7 +376,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.MonoVideo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Examples/MonoVideo/Sources/AppDelegate.swift b/Examples/MonoVideo/Sources/AppDelegate.swift index 0523049..74a614b 100644 --- a/Examples/MonoVideo/Sources/AppDelegate.swift +++ b/Examples/MonoVideo/Sources/AppDelegate.swift @@ -11,8 +11,8 @@ import UIKit @UIApplicationMain final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = ViewController() window?.makeKeyAndVisible() diff --git a/Examples/MonoVideo/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/MonoVideo/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json index 5316a54..1ea0c1a 100644 --- a/Examples/MonoVideo/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Examples/MonoVideo/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -89,6 +89,11 @@ "idiom" : "ipad", "filename" : "AppIcon@167.png", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/Examples/MonoVideo/Sources/ViewController.swift b/Examples/MonoVideo/Sources/ViewController.swift index c071fd2..79cb3d2 100644 --- a/Examples/MonoVideo/Sources/ViewController.swift +++ b/Examples/MonoVideo/Sources/ViewController.swift @@ -12,6 +12,12 @@ import MetalScope import AVFoundation final class ViewController: UIViewController { + + typealias SeekOperationBlock = () -> Void + + fileprivate var timeObserverToken: Any? + fileprivate var isSeeking: Bool = false + lazy var device: MTLDevice = { guard let device = MTLCreateSystemDefaultDevice() else { fatalError("Failed to create MTLDevice") @@ -20,7 +26,8 @@ final class ViewController: UIViewController { }() weak var panoramaView: PanoramaView? - + fileprivate var slider: UISlider! + var player: AVPlayer? var playerLooper: Any? // AVPlayerLooper if available var playerObservingToken: Any? @@ -29,6 +36,8 @@ final class ViewController: UIViewController { if let token = playerObservingToken { NotificationCenter.default.removeObserver(token) } + + removePeriodicTimeObserver() } private func loadPanoramaView() { @@ -36,18 +45,30 @@ final class ViewController: UIViewController { panoramaView.setNeedsResetRotation() panoramaView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(panoramaView) + + slider = UISlider(frame: CGRect(x: 30, y: view.bounds.height - 60, width: view.bounds.width - 60, height: 30)) + slider.minimumValue = 0 + slider.maximumValue = 1 + slider.isContinuous = true + slider.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(slider) // fill parent view let constraints: [NSLayoutConstraint] = [ panoramaView.topAnchor.constraint(equalTo: view.topAnchor), panoramaView.bottomAnchor.constraint(equalTo: view.bottomAnchor), panoramaView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - panoramaView.trailingAnchor.constraint(equalTo: view.trailingAnchor) + panoramaView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + + slider.heightAnchor.constraint(equalToConstant: 30.0), + slider.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40), + slider.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30), + slider.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30) ] NSLayoutConstraint.activate(constraints) // double tap to reset rotation - let doubleTapGestureRecognizer = UITapGestureRecognizer(target: panoramaView, action: #selector(PanoramaView.setNeedsResetRotation(_:))) + let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(resetRotation)) doubleTapGestureRecognizer.numberOfTapsRequired = 2 panoramaView.addGestureRecognizer(doubleTapGestureRecognizer) @@ -55,6 +76,8 @@ final class ViewController: UIViewController { let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(togglePlaying)) singleTapGestureRecognizer.require(toFail: doubleTapGestureRecognizer) panoramaView.addGestureRecognizer(singleTapGestureRecognizer) + + slider.addTarget(self, action: #selector(seekVideo), for: .valueChanged) self.panoramaView = panoramaView } @@ -74,10 +97,11 @@ final class ViewController: UIViewController { } else { player.actionAtItemEnd = .none playerObservingToken = NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: playerItem, queue: nil) { _ in - player.seek(to: kCMTimeZero, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) + player.seek(to: CMTime.zero, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) } } - + + addPeriodicTimeObserver() player.play() } @@ -98,7 +122,7 @@ final class ViewController: UIViewController { return .lightContent } - func togglePlaying() { + @objc func togglePlaying() { guard let player = player else { return } @@ -109,4 +133,54 @@ final class ViewController: UIViewController { player.pause() } } + + @objc func resetRotation() { + panoramaView?.setNeedsResetRotation() + } + + @objc func seekVideo(_ slider: UISlider) { + guard !isSeeking else { return } + guard let videoDuration = self.player?.currentItem?.duration else { + return + } + isSeeking = true + removePeriodicTimeObserver() + let tolerance = CMTime.zero + let time = CMTime(seconds: videoDuration.seconds * Double(slider.value), preferredTimescale: videoDuration.timescale) + player?.seek(to: time, toleranceBefore: tolerance, toleranceAfter: tolerance, completionHandler: { [weak self] (finished) in + self?.addPeriodicTimeObserver() + self?.isSeeking = false + print("seek result: \(finished)") + }) + } +} + +fileprivate extension ViewController { + + func addPeriodicTimeObserver() { + // Invoke callback every half second + let interval = CMTime(seconds: 0.5, preferredTimescale: CMTimeScale(NSEC_PER_SEC)) + // Queue on which to invoke the callback + let mainQueue = DispatchQueue.main + // Add time observer + timeObserverToken = player?.addPeriodicTimeObserver(forInterval: interval, queue: mainQueue) { [weak self] time in + self?.updateSlider() + } + } + + func removePeriodicTimeObserver() { + if let token = timeObserverToken { + player?.removeTimeObserver(token) + timeObserverToken = nil + } + } + + func updateSlider() { + guard let videoDuration = self.player?.currentItem?.duration.seconds else { + return + } + + let currentPlayOffset = self.player!.currentTime().seconds + slider.value = Float(currentPlayOffset / videoDuration) + } } diff --git a/Examples/StereoImage/Sources/AppDelegate.swift b/Examples/StereoImage/Sources/AppDelegate.swift index ebada16..18a8e09 100644 --- a/Examples/StereoImage/Sources/AppDelegate.swift +++ b/Examples/StereoImage/Sources/AppDelegate.swift @@ -11,8 +11,8 @@ import UIKit @UIApplicationMain final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.tintColor = .white window?.rootViewController = ViewController() diff --git a/Examples/StereoImage/Sources/ViewController.swift b/Examples/StereoImage/Sources/ViewController.swift index 8d1e815..8464f10 100644 --- a/Examples/StereoImage/Sources/ViewController.swift +++ b/Examples/StereoImage/Sources/ViewController.swift @@ -36,7 +36,7 @@ final class ViewController: UIViewController { NSLayoutConstraint.activate(constraints) // double tap to reset rotation - let doubleTapGestureRecognizer = UITapGestureRecognizer(target: panoramaView, action: #selector(PanoramaView.setNeedsResetRotation(_:))) + let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(resetRotation)) doubleTapGestureRecognizer.numberOfTapsRequired = 2 panoramaView.addGestureRecognizer(doubleTapGestureRecognizer) @@ -94,7 +94,7 @@ final class ViewController: UIViewController { return .lightContent } - func presentStereoView() { + @objc func presentStereoView() { let introView = UILabel() introView.text = "Place your phone into your Cardboard viewer." introView.textColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) @@ -106,4 +106,8 @@ final class ViewController: UIViewController { stereoViewController.scene = panoramaView?.scene present(stereoViewController, animated: true, completion: nil) } + + @objc func resetRotation() { + panoramaView?.setNeedsResetRotation() + } } diff --git a/Examples/StereoImage/StereoImage.xcodeproj/project.pbxproj b/Examples/StereoImage/StereoImage.xcodeproj/project.pbxproj index 158b8c2..46d1200 100644 --- a/Examples/StereoImage/StereoImage.xcodeproj/project.pbxproj +++ b/Examples/StereoImage/StereoImage.xcodeproj/project.pbxproj @@ -146,7 +146,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0820; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "eje Inc."; TargetAttributes = { BF1453111E322A440042598E = { @@ -157,7 +157,7 @@ }; buildConfigurationList = BF14530D1E322A440042598E /* Build configuration list for PBXProject "StereoImage" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -242,6 +242,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -251,6 +252,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -258,6 +260,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -296,6 +299,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -305,6 +309,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -312,6 +317,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -350,7 +356,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.StereoImage"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -366,7 +372,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.StereoImage"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Examples/StereoVideo/Sources/AppDelegate.swift b/Examples/StereoVideo/Sources/AppDelegate.swift index baf6e96..e58c1c3 100644 --- a/Examples/StereoVideo/Sources/AppDelegate.swift +++ b/Examples/StereoVideo/Sources/AppDelegate.swift @@ -12,7 +12,7 @@ import UIKit class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.tintColor = .white window?.rootViewController = ViewController() diff --git a/Examples/StereoVideo/Sources/ViewController.swift b/Examples/StereoVideo/Sources/ViewController.swift index e6b1625..9b9f0c4 100644 --- a/Examples/StereoVideo/Sources/ViewController.swift +++ b/Examples/StereoVideo/Sources/ViewController.swift @@ -47,7 +47,7 @@ final class ViewController: UIViewController { NSLayoutConstraint.activate(constraints) // double tap to reset rotation - let doubleTapGestureRecognizer = UITapGestureRecognizer(target: panoramaView, action: #selector(PanoramaView.setNeedsResetRotation(_:))) + let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(resetRotation)) doubleTapGestureRecognizer.numberOfTapsRequired = 2 panoramaView.addGestureRecognizer(doubleTapGestureRecognizer) @@ -74,7 +74,7 @@ final class ViewController: UIViewController { } else { player.actionAtItemEnd = .none playerObservingToken = NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: playerItem, queue: nil) { _ in - player.seek(to: kCMTimeZero, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) + player.seek(to: CMTime.zero, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) } } @@ -131,7 +131,7 @@ final class ViewController: UIViewController { return .lightContent } - func togglePlaying() { + @objc func togglePlaying() { guard let player = player else { return } @@ -143,7 +143,7 @@ final class ViewController: UIViewController { } } - func presentStereoView() { + @objc func presentStereoView() { let introView = UILabel() introView.text = "Place your phone into your Cardboard viewer." introView.textColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) @@ -156,4 +156,8 @@ final class ViewController: UIViewController { stereoViewController.stereoView.tapGestureRecognizer.addTarget(self, action: #selector(togglePlaying)) present(stereoViewController, animated: true, completion: nil) } + + @objc func resetRotation() { + panoramaView?.setNeedsResetRotation() + } } diff --git a/Examples/StereoVideo/StereoVideo.xcodeproj/project.pbxproj b/Examples/StereoVideo/StereoVideo.xcodeproj/project.pbxproj index c53460d..cacaf7d 100644 --- a/Examples/StereoVideo/StereoVideo.xcodeproj/project.pbxproj +++ b/Examples/StereoVideo/StereoVideo.xcodeproj/project.pbxproj @@ -149,7 +149,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0820; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "eje Inc."; TargetAttributes = { BF9B15CA1E488AF3004CC8CE = { @@ -160,7 +160,7 @@ }; buildConfigurationList = BF9B15C61E488AF3004CC8CE /* Build configuration list for PBXProject "StereoVideo" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -246,6 +246,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -255,6 +256,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -262,6 +264,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -300,6 +303,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -309,6 +313,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -316,6 +321,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -354,7 +360,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.StereoVideo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -370,7 +376,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope.StereoVideo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/MetalScope.xcodeproj/project.pbxproj b/MetalScope.xcodeproj/project.pbxproj index 7d830cd..3073bd2 100644 --- a/MetalScope.xcodeproj/project.pbxproj +++ b/MetalScope.xcodeproj/project.pbxproj @@ -258,11 +258,12 @@ BFB8916F1E2E013400FA9129 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "eje Inc."; TargetAttributes = { BFB891771E2E013400FA9129 = { CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = 77879KDM34; LastSwiftMigration = 0820; ProvisioningStyle = Automatic; }; @@ -270,10 +271,11 @@ }; buildConfigurationList = BFB891721E2E013400FA9129 /* Build configuration list for PBXProject "MetalScope" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = BFB8916E1E2E013400FA9129; productRefGroup = BFB891791E2E013400FA9129 /* Products */; @@ -346,6 +348,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -355,6 +358,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -362,6 +366,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -405,6 +410,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -414,6 +420,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -421,6 +428,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -457,10 +465,10 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 77879KDM34; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -471,7 +479,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -482,7 +490,7 @@ CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 77879KDM34; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -492,7 +500,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.eje-c.MetalScope"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/MetalScope.xcodeproj/xcshareddata/xcschemes/MetalScope.xcscheme b/MetalScope.xcodeproj/xcshareddata/xcschemes/MetalScope.xcscheme index acbc580..6f13c81 100644 --- a/MetalScope.xcodeproj/xcshareddata/xcschemes/MetalScope.xcscheme +++ b/MetalScope.xcodeproj/xcshareddata/xcschemes/MetalScope.xcscheme @@ -1,6 +1,6 @@ Bool { diff --git a/Sources/RenderLoop.swift b/Sources/RenderLoop.swift index f95f829..5da6eec 100644 --- a/Sources/RenderLoop.swift +++ b/Sources/RenderLoop.swift @@ -19,7 +19,7 @@ public final class RenderLoop { private lazy var displayLink: CADisplayLink = { let link = CADisplayLink(target: self, selector: #selector(handleDisplayLink(_:))) - link.add(to: .main, forMode: .commonModes) + link.add(to: .main, forMode: RunLoop.Mode.common) link.isPaused = true return link }() diff --git a/Sources/StereoRenderer.swift b/Sources/StereoRenderer.swift index 3fd4208..efc6a81 100644 --- a/Sources/StereoRenderer.swift +++ b/Sources/StereoRenderer.swift @@ -52,8 +52,8 @@ internal final class StereoRenderer { eyeTextureDescriptor.usage = .renderTarget eyeRenderingConfigurations = [ - .left: EyeRenderingConfiguration(texture: device.makeTexture(descriptor: eyeTextureDescriptor)), - .right: EyeRenderingConfiguration(texture: device.makeTexture(descriptor: eyeTextureDescriptor)) + .left: EyeRenderingConfiguration(texture: device.makeTexture(descriptor: eyeTextureDescriptor)!), + .right: EyeRenderingConfiguration(texture: device.makeTexture(descriptor: eyeTextureDescriptor)!) ] } @@ -89,7 +89,7 @@ internal final class StereoRenderer { passDescriptor.colorAttachments[0].loadAction = .clear scnRenderer.pointOfView = configuration.pointOfView - scnRenderer.render(atTime: time, viewport: viewport, commandBuffer: commandBuffer, passDescriptor: passDescriptor) + scnRenderer.render(atTime: time, viewport: viewport, commandBuffer: commandBuffer!, passDescriptor: passDescriptor) let destinationOrigin: MTLOrigin switch eye { @@ -99,7 +99,7 @@ internal final class StereoRenderer { destinationOrigin = MTLOrigin(x: outputTexture.width / 2, y: 0, z: 0) } - let blitCommandEncoder = commandBuffer.makeBlitCommandEncoder() + let blitCommandEncoder = commandBuffer!.makeBlitCommandEncoder()! blitCommandEncoder.copy( from: texture, sourceSlice: 0, @@ -113,11 +113,11 @@ internal final class StereoRenderer { ) blitCommandEncoder.endEncoding() - commandBuffer.addCompletedHandler { _ in + commandBuffer!.addCompletedHandler { _ in semaphore.signal() } - commandBuffer.commit() + commandBuffer!.commit() } } } @@ -137,6 +137,8 @@ extension MTLCommandBufferStatus: CustomStringConvertible { return "notEnqueued" case .scheduled: return "scheduled" + @unknown default: + return "unknown" } } } diff --git a/Sources/StereoScene.swift b/Sources/StereoScene.swift index 105ea48..bd11742 100644 --- a/Sources/StereoScene.swift +++ b/Sources/StereoScene.swift @@ -57,7 +57,7 @@ internal final class StereoScene: SCNScene { let mesh = SCNGeometry( sources: [ - SCNGeometrySource(vertices: vertices, count: vertices.count), + SCNGeometrySource(vertices: vertices), SCNGeometrySource(texcoord: texcoord), SCNGeometrySource(colors: colors) ], diff --git a/Sources/StereoView.swift b/Sources/StereoView.swift index 1819d76..ad51305 100644 --- a/Sources/StereoView.swift +++ b/Sources/StereoView.swift @@ -144,7 +144,7 @@ public final class StereoView: UIView, SceneLoadable { height: Int(textureSize.height), mipmapped: true ) - let texture = device.makeTexture(descriptor: textureDescriptor) + let texture = device.makeTexture(descriptor: textureDescriptor)! self.init(stereoTexture: texture) diff --git a/Sources/StereoViewController.swift b/Sources/StereoViewController.swift index 71cb12a..0b4331b 100644 --- a/Sources/StereoViewController.swift +++ b/Sources/StereoViewController.swift @@ -11,7 +11,7 @@ import SceneKit open class StereoViewController: UIViewController, SceneLoadable { #if (arch(arm) || arch(arm64)) && os(iOS) - open let device: MTLDevice + public let device: MTLDevice #endif open var scene: SCNScene? { @@ -344,7 +344,7 @@ open class StereoViewController: UIViewController, SceneLoadable { precondition(introductionViewUpdateTimer == nil) let timer = DispatchSource.makeTimerSource(queue: .main) - timer.scheduleRepeating(deadline: .now() + delay, interval: interval) + timer.schedule(deadline: .now() + delay, repeating: interval) timer.setEventHandler { [weak self] in guard self?.isViewLoaded == true, let _ = self?.introductionView else { return diff --git a/Sources/VideoScene.swift b/Sources/VideoScene.swift index 00fc5b9..2396f7f 100644 --- a/Sources/VideoScene.swift +++ b/Sources/VideoScene.swift @@ -75,7 +75,7 @@ public final class MonoSphericalVideoScene: MonoSphericalMediaScene, VideoScene public init(renderer: PlayerRenderer) { self.renderer = renderer - commandQueue = renderer.device.makeCommandQueue() + commandQueue = renderer.device.makeCommandQueue()! super.init() renderLoop.resume() } @@ -116,8 +116,8 @@ public final class MonoSphericalVideoScene: MonoSphericalMediaScene, VideoScene do { let commandBuffer = (commandQueue ?? self.commandQueue).makeCommandBuffer() - try renderer.render(atHostTime: time, to: texture, commandBuffer: commandBuffer) - commandBuffer.commit() + try renderer.render(atHostTime: time, to: texture, commandBuffer: commandBuffer!) + commandBuffer!.commit() } catch let error as CVError { debugPrint("[MonoSphericalVideoScene] failed to render video with error: \(error)") } catch { @@ -163,7 +163,7 @@ public final class StereoSphericalVideoScene: StereoSphericalMediaScene, VideoSc public init(renderer: PlayerRenderer) { self.renderer = renderer - commandQueue = renderer.device.makeCommandQueue() + commandQueue = renderer.device.makeCommandQueue()! super.init() renderLoop.resume() } @@ -209,10 +209,10 @@ public final class StereoSphericalVideoScene: StereoSphericalMediaScene, VideoSc let commandBuffer = (commandQueue ?? self.commandQueue).makeCommandBuffer() do { - try renderer.render(atHostTime: time, to: playerTexture, commandBuffer: commandBuffer) + try renderer.render(atHostTime: time, to: playerTexture, commandBuffer: commandBuffer!) func copyPlayerTexture(region: MTLRegion, to sphereTexture: MTLTexture) { - let blitCommandEncoder = commandBuffer.makeBlitCommandEncoder() + let blitCommandEncoder = commandBuffer!.makeBlitCommandEncoder()! blitCommandEncoder.copy( from: playerTexture, sourceSlice: 0, @@ -239,7 +239,7 @@ public final class StereoSphericalVideoScene: StereoSphericalMediaScene, VideoSc copyPlayerTexture(region: rightSphereRegion, to: rightTexture) } - commandBuffer.commit() + commandBuffer!.commit() } catch let error as CVError { debugPrint("[StereoSphericalVideoScene] failed to render video with error: \(error)") } catch {