diff --git a/FaceTracking.xcodeproj/project.pbxproj b/FaceTracking.xcodeproj/project.pbxproj index 31b57b6..f8bef25 100644 --- a/FaceTracking.xcodeproj/project.pbxproj +++ b/FaceTracking.xcodeproj/project.pbxproj @@ -103,12 +103,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = "Pawel Chmiel"; TargetAttributes = { E5AB7BCD1D9E92DA0079BE5B = { CreatedOnToolsVersion = 8.0; - DevelopmentTeam = 27FAFL2WP5; + LastSwiftMigration = 0920; ProvisioningStyle = Automatic; }; }; @@ -185,7 +185,9 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -193,7 +195,12 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -216,12 +223,13 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -235,7 +243,9 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -243,7 +253,12 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -260,10 +275,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -273,13 +289,17 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = 27FAFL2WP5; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = FaceTracking/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.droidsonroids.FaceTracking; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -287,13 +307,17 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = 27FAFL2WP5; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = FaceTracking/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.droidsonroids.FaceTracking; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -316,6 +340,7 @@ E5AB7BE21D9E92DA0079BE5B /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/FaceTracking.xcodeproj/xcshareddata/xcschemes/FaceTracking.xcscheme b/FaceTracking.xcodeproj/xcshareddata/xcschemes/FaceTracking.xcscheme index 37b0813..f81b6a7 100644 --- a/FaceTracking.xcodeproj/xcshareddata/xcschemes/FaceTracking.xcscheme +++ b/FaceTracking.xcodeproj/xcshareddata/xcschemes/FaceTracking.xcscheme @@ -1,6 +1,6 @@ @@ -45,6 +46,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/FaceTracking/Assets.xcassets/AppIcon.appiconset/Contents.json b/FaceTracking/Assets.xcassets/AppIcon.appiconset/Contents.json index 1d060ed..d8db8d6 100644 --- a/FaceTracking/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/FaceTracking/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -84,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/FaceTracking/Info.plist b/FaceTracking/Info.plist index d052473..8334cd2 100644 --- a/FaceTracking/Info.plist +++ b/FaceTracking/Info.plist @@ -20,6 +20,8 @@ 1 LSRequiresIPhoneOS + NSCameraUsageDescription + App requires camera to demo face tracking UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -28,11 +30,11 @@ armv7 + UIRequiresFullScreen + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad diff --git a/FaceTracking/ViewController.swift b/FaceTracking/ViewController.swift index 2d25105..fe4d300 100644 --- a/FaceTracking/ViewController.swift +++ b/FaceTracking/ViewController.swift @@ -41,7 +41,7 @@ class DetailsView: UIView { class ViewController: UIViewController { var session: AVCaptureSession? - var stillOutput = AVCaptureStillImageOutput() + var stillOutput = AVCapturePhotoOutput() var borderLayer: CAShapeLayer? let detailsView: DetailsView = { @@ -53,15 +53,15 @@ class ViewController: UIViewController { lazy var previewLayer: AVCaptureVideoPreviewLayer? = { var previewLay = AVCaptureVideoPreviewLayer(session: self.session!) - previewLay?.videoGravity = AVLayerVideoGravityResizeAspectFill + previewLay.videoGravity = AVLayerVideoGravity.resizeAspectFill return previewLay }() lazy var frontCamera: AVCaptureDevice? = { - guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else { return nil } + let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: .video, position: AVCaptureDevice.Position.front) - return devices.filter { $0.position == .front }.first + return discoverySession.devices.first }() let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyLow]) @@ -94,7 +94,7 @@ extension ViewController { guard let session = session, let captureDevice = frontCamera else { return } - session.sessionPreset = AVCaptureSessionPresetPhoto + session.sessionPreset = AVCaptureSession.Preset.photo do { let deviceInput = try AVCaptureDeviceInput(device: captureDevice) @@ -125,10 +125,11 @@ extension ViewController { } extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate { - func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { - let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) - let attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate) - let ciImage = CIImage(cvImageBuffer: pixelBuffer!, options: attachments as! [String : Any]?) + func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { + + guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return } + guard let attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate) else { return } + let ciImage = CIImage(cvImageBuffer: pixelBuffer, options: (attachments as! [String : Any])) let options: [String : Any] = [CIDetectorImageOrientation: exifOrientation(orientation: UIDevice.current.orientation), CIDetectorSmile: true, CIDetectorEyeBlink: true] @@ -143,9 +144,9 @@ extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate { if let faceFeature = feature as? CIFaceFeature { let faceRect = calculateFaceRect(facePosition: faceFeature.mouthPosition, faceBounds: faceFeature.bounds, clearAperture: cleanAperture) let featureDetails = ["has smile: \(faceFeature.hasSmile)", - "has closed left eye: \(faceFeature.leftEyeClosed)", - "has closed right eye: \(faceFeature.rightEyeClosed)"] - + "has closed right eye: \(faceFeature.rightEyeClosed)", + "has closed left eye: \(faceFeature.leftEyeClosed)"] + update(with: faceRect, text: featureDetails.joined(separator: "\n")) } }