From fce8165b1582f211e1ceaf3f512e8290cdec8531 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Sun, 18 Dec 2016 19:58:37 +0200 Subject: [PATCH 01/23] Fixes a typo --- .../Samples/MetalImageRecognitionViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift b/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift index f3fddd2..95ae978 100644 --- a/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift +++ b/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift @@ -101,7 +101,7 @@ class MetalImageRecognitionViewController: UIViewController, UIImagePickerContro } /** - This function gets a commanBuffer and encodes layers in it. It follows that by commiting the commandBuffer and getting labels + This function gets a commandBuffer and encodes layers in it. It follows that by commiting the commandBuffer and getting labels */ func runNetwork() { let startTime = CACurrentMediaTime() From e483ff8c1807a6e85838d7554183b4991892c14f Mon Sep 17 00:00:00 2001 From: shu223 Date: Fri, 24 Feb 2017 18:43:13 +0900 Subject: [PATCH 02/23] minor fixes --- iOS-10-Sampler/Samples/MNISTDeepCNN.swift | 2 +- .../Samples/MetalCNNBasicViewController.swift | 9 +++++++-- .../Samples/MetalImageRecognitionViewController.swift | 11 ++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/iOS-10-Sampler/Samples/MNISTDeepCNN.swift b/iOS-10-Sampler/Samples/MNISTDeepCNN.swift index c460198..3086c5e 100644 --- a/iOS-10-Sampler/Samples/MNISTDeepCNN.swift +++ b/iOS-10-Sampler/Samples/MNISTDeepCNN.swift @@ -38,7 +38,7 @@ class MNISTDeepCNN { var commandQueue : MTLCommandQueue var device : MTLDevice - init(withCommandQueue commandQueueIn: MTLCommandQueue!) { + init(withCommandQueue commandQueueIn: MTLCommandQueue) { commandQueue = commandQueueIn device = commandQueueIn.device diff --git a/iOS-10-Sampler/Samples/MetalCNNBasicViewController.swift b/iOS-10-Sampler/Samples/MetalCNNBasicViewController.swift index f389b97..4db6541 100644 --- a/iOS-10-Sampler/Samples/MetalCNNBasicViewController.swift +++ b/iOS-10-Sampler/Samples/MetalCNNBasicViewController.swift @@ -33,7 +33,12 @@ class MetalCNNBasicViewController: UIViewController { predictionLabel.text = nil // Load default device. - device = MTLCreateSystemDefaultDevice() + guard let device = MTLCreateSystemDefaultDevice() else { + showAlert(title: "Not Supported", message: "Metal is not supported on current device", handler: { (action) in + self.navigationController!.popViewController(animated: true) + }) + return + } // Make sure the current device supports MetalPerformanceShaders. guard MPSSupportsMTLDevice(device) else { @@ -44,7 +49,7 @@ class MetalCNNBasicViewController: UIViewController { } // Create new command queue. - commandQueue = device!.makeCommandQueue() + commandQueue = device.makeCommandQueue() // initialize the networks we shall use to detect digits network = MNISTDeepCNN(withCommandQueue: commandQueue) diff --git a/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift b/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift index f3fddd2..00cc3ee 100644 --- a/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift +++ b/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift @@ -32,7 +32,12 @@ class MetalImageRecognitionViewController: UIViewController, UIImagePickerContro super.viewDidLoad() // Load default device. - device = MTLCreateSystemDefaultDevice() + guard let device = MTLCreateSystemDefaultDevice() else { + showAlert(title: "Not Supported", message: "Metal is not supported on current device", handler: { (action) in + self.navigationController!.popViewController(animated: true) + }) + return + } // Make sure the current device supports MetalPerformanceShaders. guard MPSSupportsMTLDevice(device) else { @@ -64,10 +69,10 @@ class MetalImageRecognitionViewController: UIViewController, UIImagePickerContro // Load any resources required for rendering. // Create new command queue. - commandQueue = device!.makeCommandQueue() + commandQueue = device.makeCommandQueue() // make a textureLoader to get our input images as MTLTextures - textureLoader = MTKTextureLoader(device: device!) + textureLoader = MTKTextureLoader(device: device) // Load the appropriate Network inception3Net = Inception3Net(withCommandQueue: commandQueue) From 4c799e4ff3b1628f793b88320df05ac061c16479 Mon Sep 17 00:00:00 2001 From: shu223 Date: Fri, 7 Apr 2017 16:15:01 -0700 Subject: [PATCH 03/23] Resolved warnings on Xcode 8.3 --- iOS-10-Sampler/Samples/LivePhotoCaptureDelegate.swift | 5 ++--- libs/VideoCapture/AVCaptureDevice+Extension.swift | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iOS-10-Sampler/Samples/LivePhotoCaptureDelegate.swift b/iOS-10-Sampler/Samples/LivePhotoCaptureDelegate.swift index 3e1ead5..f469add 100644 --- a/iOS-10-Sampler/Samples/LivePhotoCaptureDelegate.swift +++ b/iOS-10-Sampler/Samples/LivePhotoCaptureDelegate.swift @@ -73,9 +73,8 @@ class LivePhotoCaptureDelegate: NSObject, AVCapturePhotoCaptureDelegate { if let photoSampleBuffer = photoSampleBuffer { photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) } - else { + else if let error = error { print("Error capturing photo: \(error)") - return } } @@ -84,7 +83,7 @@ class LivePhotoCaptureDelegate: NSObject, AVCapturePhotoCaptureDelegate { } func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingLivePhotoToMovieFileAt outputFileURL: URL, duration: CMTime, photoDisplay photoDisplayTime: CMTime, resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) { - if let _ = error { + if let error = error { print("Error processing live photo companion movie: \(error)") return } diff --git a/libs/VideoCapture/AVCaptureDevice+Extension.swift b/libs/VideoCapture/AVCaptureDevice+Extension.swift index 043808f..0acdfe7 100644 --- a/libs/VideoCapture/AVCaptureDevice+Extension.swift +++ b/libs/VideoCapture/AVCaptureDevice+Extension.swift @@ -76,7 +76,7 @@ extension AVCaptureDevice { } else { selectedFormat = formatWithHighestResolution(availableFormats) } - print("selected format: \(selectedFormat)") + print("selected format: \(String(describing: selectedFormat))") if let selectedFormat = selectedFormat { do { From ead005802d27f5413ef60b34af345e2033c673ba Mon Sep 17 00:00:00 2001 From: shu223 Date: Sun, 7 May 2017 00:35:28 +0900 Subject: [PATCH 04/23] Update README.md --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index fd3c590..3d3ff37 100644 --- a/README.md +++ b/README.md @@ -12,127 +12,127 @@ Code examples for new APIs of iOS 10. -##How to build +## How to build Just build with Xcode 8. It can **NOT** run on **Simulator**. (Because it uses Metal.) -##Contents +## Contents -###Speech Recognition +### Speech Recognition Speech Recognition demo using Speech Framework. All available languages can be selected. -###Looper +### Looper Loop playback demo using AVPlayerLooper.
-###Live Photo Capturing +### Live Photo Capturing Live Photo Capturing example using AVCapturePhotoOutput. -###Audio Fade-in/out +### Audio Fade-in/out Audio fade-in/out demo using `setVolume:fadeDuration` method which is added to AVAudioPlayer. -###Metal CNN Basic: Digit Detection +### Metal CNN Basic: Digit Detection Hand-writing digit detection using CNN (Convolutional Neural Network) by Metal Performance Shaders. -###Metal CNN Advanced: Image Recognition +### Metal CNN Advanced: Image Recognition Real-time image recognition using CNN (Convolutional Neural Network) by Metal Performance Shaders. -###PropertyAnimator: Position +### PropertyAnimator: Position Animating UIView's `center` & `backgroundColor` using UIViewPropertyAnimator. -###PropertyAnimator: Blur +### PropertyAnimator: Blur Animating blur effect using `fractionComplete` property of UIViewPropertyAnimator. -###Preview Interaction +### Preview Interaction **Peek & Pop interactions with 3D touch** using UIPreviewInteraction. -###Notification with Image +### Notification with Image Local notification with an image using UserNotifications framework.
-###Sticker Pack +### Sticker Pack Example of Sticker Pack for iMessage. -###Core Data Stack (Created by [nolili](https://github.com/nolili)) +### Core Data Stack (Created by [nolili](https://github.com/nolili)) Simple Core Data stack using NSPersistentContainer. -###TabBar Customization +### TabBar Customization Customization sample for UITabBar's badge using text attributes. -###New filters +### New filters New filters of CIFilter in Core Image.
-###New Fonts +### New Fonts New Fonts gallery -###Proactive: Location Suggestions +### Proactive: Location Suggestions This sample demonstrates how to use new `mapItem` property of NSUserActivity to integrate with location suggestions.
-###Attributed Speech +### Attributed Speech Attributed Speech demo using `attributedSpeechString` of AVSpeechUtterance. But it seems **NOT** to affect the speech with this attribute. Anyone, please let me know how to use this new API. -###Haptic Feedback +### Haptic Feedback Haptic Feedbacks using UIFeedbackGenerator. -##Author +## Author **Shuichi Tsutsumi** @@ -144,6 +144,6 @@ Freelance iOS programmer in Japan. - CONTACTS: [Twitter](https://twitter.com/shu223) / [Facebook](https://www.facebook.com/shuichi.tsutsumi) -##Special Thanks +## Special Thanks The icon is designed by [Okazu](https://www.facebook.com/pashimo) From 0d3bd7fd211f825c26ca3b60b244bb409166de3c Mon Sep 17 00:00:00 2001 From: Shuichi Tsutsumi Date: Wed, 20 Sep 2017 20:54:29 +0900 Subject: [PATCH 05/23] Fixes with Xcode 9 (#14) * Update with Xcode 9 * Fixed AVFoundation changes * Fixed changes of NSAttriubtedString * Fixed MPSCNN sample for iOS 11 / Swift 4 / Xcode 9 * Fixed more * more fixes * Error: the descriptor must be configured with MTLStorageModePrivate' * commented out * updated .gitignore * Fixed build errors * Fixed build errors * Disabled "Swift 3 @objc inference" --- .gitignore | 2 + iOS-10-Sampler.xcodeproj/project.pbxproj | 35 ++++++++-- .../xcschemes/iOS-10-Sampler.xcscheme | 2 +- .../AttributedSpeechViewController.swift | 6 +- iOS-10-Sampler/Samples/Inception3Net.swift | 6 +- .../Samples/LivePhotoCaptureDelegate.swift | 10 +-- .../LivePhotoCaptureSessionManager.swift | 24 +++---- .../LivePhotoCaptureViewController.swift | 4 +- iOS-10-Sampler/Samples/Looper.swift | 2 +- iOS-10-Sampler/Samples/MNISTDeepCNN.swift | 2 +- .../MetalCNNBasicApple/SlimMPSCNN.swift | 37 +++++++--- .../MetalImageRecognitionViewController.swift | 16 ++--- .../SpeechRecognitionViewController.swift | 2 +- .../Samples/TabBadgeViewController.swift | 6 +- .../AVCaptureDevice+Extension.swift | 69 ++++++++----------- libs/VideoCapture/VideoCameraType.swift | 4 +- libs/VideoCapture/VideoCapture.swift | 21 +++--- 17 files changed, 138 insertions(+), 110 deletions(-) diff --git a/.gitignore b/.gitignore index cab8c69..dbc0efe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore +iOS-10-Sampler/Resources/network_params/logos + ## Build generated build/ DerivedData/ diff --git a/iOS-10-Sampler.xcodeproj/project.pbxproj b/iOS-10-Sampler.xcodeproj/project.pbxproj index 75b2346..bd44560 100644 --- a/iOS-10-Sampler.xcodeproj/project.pbxproj +++ b/iOS-10-Sampler.xcodeproj/project.pbxproj @@ -1277,7 +1277,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0810; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = "Shuichi Tsutsumi"; TargetAttributes = { 8A1CC38B1D7AC22E00562709 = { @@ -1288,17 +1288,20 @@ 8AB430541D7A6B4900A3BD98 = { CreatedOnToolsVersion = 8.0; DevelopmentTeam = 9Z86A4AWDE; + LastSwiftMigration = 0900; ProvisioningStyle = Automatic; }; 8AB430681D7A6B4A00A3BD98 = { CreatedOnToolsVersion = 8.0; DevelopmentTeam = 9Z86A4AWDE; + LastSwiftMigration = 0900; ProvisioningStyle = Automatic; TestTargetID = 8AB430541D7A6B4900A3BD98; }; 8AB430731D7A6B4A00A3BD98 = { CreatedOnToolsVersion = 8.0; DevelopmentTeam = 9Z86A4AWDE; + LastSwiftMigration = 0900; ProvisioningStyle = Automatic; TestTargetID = 8AB430541D7A6B4900A3BD98; }; @@ -1717,7 +1720,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; @@ -1725,7 +1730,11 @@ 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; @@ -1767,7 +1776,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; @@ -1775,7 +1786,11 @@ 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; @@ -1811,7 +1826,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Off; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -1825,7 +1841,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Off; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -1839,7 +1856,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOS-10-Sampler.app/iOS-10-Sampler"; }; name = Debug; @@ -1854,7 +1872,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOS-10-Sampler.app/iOS-10-Sampler"; }; name = Release; @@ -1868,7 +1887,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TEST_TARGET_NAME = "iOS-10-Sampler"; }; name = Debug; @@ -1882,7 +1902,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TEST_TARGET_NAME = "iOS-10-Sampler"; }; name = Release; diff --git a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme index d857d72..d216029 100644 --- a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme +++ b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme @@ -1,6 +1,6 @@ 0 && resolvedSettings.livePhotoMovieDimensions.height > 0 { capturingLivePhoto(true) } } - func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { + func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { if let photoSampleBuffer = photoSampleBuffer { photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) } @@ -78,11 +78,11 @@ class LivePhotoCaptureDelegate: NSObject, AVCapturePhotoCaptureDelegate { } } - func capture(_ captureOutput: AVCapturePhotoOutput, didFinishRecordingLivePhotoMovieForEventualFileAt outputFileURL: URL, resolvedSettings: AVCaptureResolvedPhotoSettings) { + func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishRecordingLivePhotoMovieForEventualFileAt outputFileURL: URL, resolvedSettings: AVCaptureResolvedPhotoSettings) { capturingLivePhoto(false) } - func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingLivePhotoToMovieFileAt outputFileURL: URL, duration: CMTime, photoDisplay photoDisplayTime: CMTime, resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) { + func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingLivePhotoToMovieFileAt outputFileURL: URL, duration: CMTime, photoDisplayTime: CMTime, resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) { if let error = error { print("Error processing live photo companion movie: \(error)") return @@ -91,7 +91,7 @@ class LivePhotoCaptureDelegate: NSObject, AVCapturePhotoCaptureDelegate { livePhotoCompanionMovieURL = outputFileURL } - func capture(_ captureOutput: AVCapturePhotoOutput, didFinishCaptureForResolvedSettings resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) { + func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) { if let error = error { print("Error capturing photo: \(error)") didFinish() diff --git a/iOS-10-Sampler/Samples/LivePhotoCaptureSessionManager.swift b/iOS-10-Sampler/Samples/LivePhotoCaptureSessionManager.swift index 48f4690..1c0638d 100644 --- a/iOS-10-Sampler/Samples/LivePhotoCaptureSessionManager.swift +++ b/iOS-10-Sampler/Samples/LivePhotoCaptureSessionManager.swift @@ -41,14 +41,14 @@ class LivePhotoCaptureSessionManager: NSObject { session.beginConfiguration() - session.sessionPreset = AVCaptureSessionPresetPhoto + session.sessionPreset = .photo // Add video input. do { - let videoDevice = AVCaptureDevice.defaultDevice( - withDeviceType: AVCaptureDeviceType.builtInWideAngleCamera, - mediaType: AVMediaTypeVideo, - position: .back) + guard let videoDevice = AVCaptureDevice.default( + .builtInWideAngleCamera, + for: .video, + position: .back) else {fatalError()} let videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice) if session.canAddInput(videoDeviceInput) { @@ -71,7 +71,7 @@ class LivePhotoCaptureSessionManager: NSObject { // Add audio input. do { - let audioDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) + guard let audioDevice = AVCaptureDevice.default(for: .audio) else {fatalError()} let audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice) if session.canAddInput(audioDeviceInput) { @@ -112,7 +112,7 @@ class LivePhotoCaptureSessionManager: NSObject { // MARK: - Public func authorize() { - switch AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) { + switch AVCaptureDevice.authorizationStatus(for: .video) { case .authorized: break @@ -126,7 +126,7 @@ class LivePhotoCaptureSessionManager: NSObject { create an AVCaptureDeviceInput for audio during session setup. */ sessionQueue.suspend() - AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { [unowned self] granted in + AVCaptureDevice.requestAccess(for: .video, completionHandler: { [unowned self] granted in if !granted { self.setupResult = .notAuthorized } @@ -182,7 +182,7 @@ class LivePhotoCaptureSessionManager: NSObject { sessionQueue.async { // Update the photo output's connection to match the video orientation of the video preview layer. - if let photoOutputConnection = self.photoOutput.connection(withMediaType: AVMediaTypeVideo) { + if let photoOutputConnection = self.photoOutput.connection(with: .video) { photoOutputConnection.videoOrientation = videoOrientation } @@ -190,9 +190,9 @@ class LivePhotoCaptureSessionManager: NSObject { let photoSettings = AVCapturePhotoSettings() photoSettings.flashMode = .auto photoSettings.isHighResolutionPhotoEnabled = true - if photoSettings.availablePreviewPhotoPixelFormatTypes.count > 0 { - photoSettings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String : photoSettings.availablePreviewPhotoPixelFormatTypes.first!] - } +// if photoSettings.availablePreviewPhotoPixelFormatTypes.count > 0 { +// photoSettings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String : photoSettings.availablePreviewPhotoPixelFormatTypes.first!] +// } if self.photoOutput.isLivePhotoCaptureSupported { // Live Photo capture is not supported in movie mode. let livePhotoMovieFileName = NSUUID().uuidString let livePhotoMovieFilePath = (NSTemporaryDirectory() as NSString).appendingPathComponent((livePhotoMovieFileName as NSString).appendingPathExtension("mov")!) diff --git a/iOS-10-Sampler/Samples/LivePhotoCaptureViewController.swift b/iOS-10-Sampler/Samples/LivePhotoCaptureViewController.swift index 93d8068..21bfaac 100644 --- a/iOS-10-Sampler/Samples/LivePhotoCaptureViewController.swift +++ b/iOS-10-Sampler/Samples/LivePhotoCaptureViewController.swift @@ -96,8 +96,8 @@ class LivePhotoCaptureViewController: UIViewController { // MARK: - Actions @IBAction private func capturePhoto(_ photoButton: UIButton) { - let videoPreviewLayerOrientation = previewView.videoPreviewLayer.connection.videoOrientation - LivePhotoCaptureSessionManager.sharedManager.capture(videoOrientation: videoPreviewLayerOrientation) { (inProgressLivePhotoCapturesCount) in + let videoPreviewLayerOrientation = previewView.videoPreviewLayer.connection?.videoOrientation + LivePhotoCaptureSessionManager.sharedManager.capture(videoOrientation: videoPreviewLayerOrientation!) { (inProgressLivePhotoCapturesCount) in DispatchQueue.main.async { [unowned self] in if inProgressLivePhotoCapturesCount > 0 { self.capturingLivePhotoLabel.isHidden = false diff --git a/iOS-10-Sampler/Samples/Looper.swift b/iOS-10-Sampler/Samples/Looper.swift index a084c93..2010760 100644 --- a/iOS-10-Sampler/Samples/Looper.swift +++ b/iOS-10-Sampler/Samples/Looper.swift @@ -40,7 +40,7 @@ class Looper: NSObject { // Getting the natural size of the video // http://stackoverflow.com/questions/14466842/ios-6-avplayeritem-presentationsize-returning-zero-naturalsize-method-deprec - let videoTracks = playerItem.asset.tracks(withMediaType: AVMediaTypeVideo) + let videoTracks = playerItem.asset.tracks(withMediaType: .video) guard let videoSize = videoTracks.first?.naturalSize else {fatalError()} parentLayer.addSublayer(playerLayer) diff --git a/iOS-10-Sampler/Samples/MNISTDeepCNN.swift b/iOS-10-Sampler/Samples/MNISTDeepCNN.swift index 3086c5e..fd56d91 100644 --- a/iOS-10-Sampler/Samples/MNISTDeepCNN.swift +++ b/iOS-10-Sampler/Samples/MNISTDeepCNN.swift @@ -116,7 +116,7 @@ class MNISTDeepCNN { // so the user can decide the appropriate time to release this autoreleasepool{ // Get command buffer to use in MetalPerformanceShaders. - let commandBuffer = commandQueue.makeCommandBuffer() + guard let commandBuffer = commandQueue.makeCommandBuffer() else {return} // output will be stored in this image let finalLayer = MPSImage(device: commandBuffer.device, imageDescriptor: did) diff --git a/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNN.swift b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNN.swift index 2b7975c..3cfdc8d 100755 --- a/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNN.swift +++ b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNN.swift @@ -21,7 +21,7 @@ class SlimMPSCNNConvolution: MPSCNNConvolution{ /** A property to keep info from init time whether we will pad input image or not for use during encode call */ - private var padding = true + internal var isPadding = true /** Initializes a fully connected kernel. @@ -34,7 +34,7 @@ class SlimMPSCNNConvolution: MPSCNNConvolution{ - neuronFilter: A neuronFilter to add at the end as activation, default is nil - device: The MTLDevice on which this SlimMPSCNNConvolution filter will be used - kernelParamsBinaryName: name of the layer to fetch kernelParameters by adding a prefix "weights_" or "bias_" - - padding: Bool value whether to use padding or not + - isPadding: Bool value whether to use padding or not - strideXY: Stride of the filter - destinationFeatureChannelOffset: FeatureChannel no. in the destination MPSImage to start writing from, helps with concat operations - groupNum: if grouping is used, default value is 1 meaning no groups @@ -93,7 +93,7 @@ class SlimMPSCNNConvolution: MPSCNNConvolution{ self.destinationFeatureChannelOffset = Int(destinationFeatureChannelOffset) // set padding for calculation of offset during encode call - padding = willPad + isPadding = willPad // unmap files at initialization of MPSCNNConvolution, the weights are copied and packed internally we no longer require these assert(munmap(hdrW, Int(sizeWeights)) == 0, "munmap failed with errno = \(errno)") @@ -104,6 +104,10 @@ class SlimMPSCNNConvolution: MPSCNNConvolution{ close(fd_b) } + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + /** Encode a MPSCNNKernel into a command Buffer. The operation shall proceed out-of-place. @@ -118,16 +122,23 @@ class SlimMPSCNNConvolution: MPSCNNConvolution{ */ override func encode(commandBuffer: MTLCommandBuffer, sourceImage: MPSImage, destinationImage: MPSImage) { // select offset according to padding being used or not - if padding { - let pad_along_height = ((destinationImage.height - 1) * strideInPixelsY + kernelHeight - sourceImage.height) - let pad_along_width = ((destinationImage.width - 1) * strideInPixelsX + kernelWidth - sourceImage.width) - let pad_top = Int(pad_along_height / 2) - let pad_left = Int(pad_along_width / 2) - - self.offset = MPSOffset(x: ((Int(kernelWidth)/2) - pad_left), y: (Int(kernelHeight/2) - pad_top), z: 0) + if isPadding { + if #available(iOS 11.0, *) { + let pad_along_height = ((destinationImage.height - 1) * strideInPixelsY + kernelHeight - sourceImage.height) + let pad_along_width = ((destinationImage.width - 1) * strideInPixelsX + kernelWidth - sourceImage.width) + let pad_top = Int(pad_along_height / 2) + let pad_left = Int(pad_along_width / 2) + self.offset = MPSOffset(x: ((Int(kernelWidth)/2) - pad_left), y: (Int(kernelHeight/2) - pad_top), z: 0) + } else { + // Fallback on earlier versions + } } else{ - self.offset = MPSOffset(x: Int(kernelWidth)/2, y: Int(kernelHeight)/2, z: 0) + if #available(iOS 11.0, *) { + self.offset = MPSOffset(x: Int(kernelWidth)/2, y: Int(kernelHeight)/2, z: 0) + } else { + // Fallback on earlier versions + } } super.encode(commandBuffer: commandBuffer, sourceImage: sourceImage, destinationImage: destinationImage) @@ -212,4 +223,8 @@ class SlimMPSCNNFullyConnected: MPSCNNFullyConnected{ close(fd_w) close(fd_b) } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } } diff --git a/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift b/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift index 309fd49..ab0103b 100644 --- a/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift +++ b/iOS-10-Sampler/Samples/MetalImageRecognitionViewController.swift @@ -57,7 +57,7 @@ class MetalImageRecognitionViewController: UIViewController, UIImagePickerContro // get a texture from this CGImage do { - self.sourceTexture = try self.textureLoader.newTexture(with: cgImage, options: [:]) + self.sourceTexture = try self.textureLoader.newTexture(cgImage: cgImage, options: nil) } catch let error as NSError { fatalError("Unexpected error ocurred: \(error.localizedDescription).") @@ -109,13 +109,12 @@ class MetalImageRecognitionViewController: UIViewController, UIImagePickerContro This function gets a commandBuffer and encodes layers in it. It follows that by commiting the commandBuffer and getting labels */ func runNetwork() { - let startTime = CACurrentMediaTime() - // to deliver optimal performance we leave some resources used in MPSCNN to be released at next call of autoreleasepool, // so the user can decide the appropriate time to release this autoreleasepool{ +// let startTime = CACurrentMediaTime() // encoding command buffer - let commandBuffer = commandQueue.makeCommandBuffer() + guard let commandBuffer = commandQueue.makeCommandBuffer() else {return} // encode all layers of network on present commandBuffer, pass in the input image MTLTexture inception3Net.forward(commandBuffer: commandBuffer, sourceTexture: sourceTexture) @@ -126,16 +125,17 @@ class MetalImageRecognitionViewController: UIViewController, UIImagePickerContro // display top-5 predictions for what the object should be labelled var resultStr = "" - inception3Net.getResults().forEach({ (label, prob) in + inception3Net.getResults().forEach({ (arg) in + + let (label, prob) = arg resultStr = resultStr + label + "\t" + String(format: "%.1f", prob * 100) + "%\n\n" }) +// let endTime = CACurrentMediaTime() +// print("Running Time: \(endTime - startTime) [sec]") DispatchQueue.main.async { self.predictLabel.text = resultStr } } - - let endTime = CACurrentMediaTime() - print("Running Time: \(endTime - startTime) [sec]") } } diff --git a/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift b/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift index 9755b57..61594f8 100644 --- a/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift +++ b/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift @@ -88,7 +88,7 @@ class SpeechRecognitionViewController: UIViewController, SFSpeechRecognizerDeleg recognitionRequest = SFSpeechAudioBufferRecognitionRequest() - guard let inputNode = audioEngine.inputNode else { fatalError("Audio engine has no input node") } + let inputNode = audioEngine.inputNode guard let recognitionRequest = recognitionRequest else { fatalError("Unable to created a SFSpeechAudioBufferRecognitionRequest object") } // Configure request so that results are returned before audio recording is finished diff --git a/iOS-10-Sampler/Samples/TabBadgeViewController.swift b/iOS-10-Sampler/Samples/TabBadgeViewController.swift index 99a837b..bef9158 100644 --- a/iOS-10-Sampler/Samples/TabBadgeViewController.swift +++ b/iOS-10-Sampler/Samples/TabBadgeViewController.swift @@ -27,9 +27,9 @@ class TabBadgeViewController: UIViewController, UITabBarDelegate { shadow.shadowColor = #colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1) shadow.shadowOffset = CGSize(width: 1, height: 1) shadow.shadowBlurRadius = 3 - let attributes: [String : Any] = [NSFontAttributeName: UIFont(name: "Menlo-Bold", size: 30)!, - NSForegroundColorAttributeName: #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1), - NSShadowAttributeName: shadow] + let attributes: [String : Any] = [NSAttributedStringKey.font.rawValue: UIFont(name: "Menlo-Bold", size: 30)!, + NSAttributedStringKey.foregroundColor.rawValue: #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1), + NSAttributedStringKey.shadow.rawValue: shadow] // New! item.setBadgeTextAttributes(attributes, for: .normal) diff --git a/libs/VideoCapture/AVCaptureDevice+Extension.swift b/libs/VideoCapture/AVCaptureDevice+Extension.swift index 0acdfe7..b31af77 100644 --- a/libs/VideoCapture/AVCaptureDevice+Extension.swift +++ b/libs/VideoCapture/AVCaptureDevice+Extension.swift @@ -8,18 +8,11 @@ import AVFoundation extension AVCaptureDevice { - private func availableFormatsFor(preferredFps: Float64) -> [AVCaptureDeviceFormat] { - guard let allFormats = formats as? [AVCaptureDeviceFormat] else { - return [] - } - - var availableFormats: [AVCaptureDeviceFormat] = [] - for format in allFormats + private func availableFormatsFor(preferredFps: Float64) -> [AVCaptureDevice.Format] { + var availableFormats: [AVCaptureDevice.Format] = [] + for format in formats { - guard let ranges = format.videoSupportedFrameRateRanges as? [AVFrameRateRange] else { - continue - } - + let ranges = format.videoSupportedFrameRateRanges for range in ranges where range.minFrameRate <= preferredFps && preferredFps <= range.maxFrameRate { availableFormats.append(format) @@ -28,13 +21,12 @@ extension AVCaptureDevice { return availableFormats } - private func formatWithHighestResolution(_ availableFormats: [AVCaptureDeviceFormat]) -> AVCaptureDeviceFormat? + private func formatWithHighestResolution(_ availableFormats: [AVCaptureDevice.Format]) -> AVCaptureDevice.Format? { var maxWidth: Int32 = 0 - var selectedFormat: AVCaptureDeviceFormat? + var selectedFormat: AVCaptureDevice.Format? for format in availableFormats { - guard let desc = format.formatDescription else {continue} - let dimensions = CMVideoFormatDescriptionGetDimensions(desc) + let dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription) let width = dimensions.width if width >= maxWidth { maxWidth = width @@ -44,11 +36,10 @@ extension AVCaptureDevice { return selectedFormat } - private func formatFor(preferredSize: CGSize, availableFormats: [AVCaptureDeviceFormat]) -> AVCaptureDeviceFormat? + private func formatFor(preferredSize: CGSize, availableFormats: [AVCaptureDevice.Format]) -> AVCaptureDevice.Format? { for format in availableFormats { - guard let desc = format.formatDescription else {continue} - let dimensions = CMVideoFormatDescriptionGetDimensions(desc) + let dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription) if dimensions.width >= Int32(preferredSize.width) && dimensions.height >= Int32(preferredSize.height) { @@ -61,37 +52,33 @@ extension AVCaptureDevice { func updateFormatWithPreferredVideoSpec(preferredSpec: VideoSpec) { - let availableFormats: [AVCaptureDeviceFormat] + let availableFormats: [AVCaptureDevice.Format] if let preferredFps = preferredSpec.fps { availableFormats = availableFormatsFor(preferredFps: Float64(preferredFps)) - } - else { - guard let allFormats = formats as? [AVCaptureDeviceFormat] else { return } - availableFormats = allFormats + } else { + availableFormats = formats } - var selectedFormat: AVCaptureDeviceFormat? + var format: AVCaptureDevice.Format? if let preferredSize = preferredSpec.size { - selectedFormat = formatFor(preferredSize: preferredSize, availableFormats: availableFormats) + format = formatFor(preferredSize: preferredSize, availableFormats: availableFormats) } else { - selectedFormat = formatWithHighestResolution(availableFormats) + format = formatWithHighestResolution(availableFormats) } - print("selected format: \(String(describing: selectedFormat))") - if let selectedFormat = selectedFormat { - do { - try lockForConfiguration() - } - catch { - fatalError("") - } - activeFormat = selectedFormat - - if let preferredFps = preferredSpec.fps { - activeVideoMinFrameDuration = CMTimeMake(1, preferredFps) - activeVideoMaxFrameDuration = CMTimeMake(1, preferredFps) - unlockForConfiguration() - } + guard let selectedFormat = format else {return} + print("selected format: \(selectedFormat)") + do { + try lockForConfiguration() + } catch { + fatalError("") + } + activeFormat = selectedFormat + + if let preferredFps = preferredSpec.fps { + activeVideoMinFrameDuration = CMTimeMake(1, preferredFps) + activeVideoMaxFrameDuration = CMTimeMake(1, preferredFps) + unlockForConfiguration() } } } diff --git a/libs/VideoCapture/VideoCameraType.swift b/libs/VideoCapture/VideoCameraType.swift index ebafd4f..67ac593 100644 --- a/libs/VideoCapture/VideoCameraType.swift +++ b/libs/VideoCapture/VideoCameraType.swift @@ -15,7 +15,7 @@ enum CameraType : Int { func captureDevice() -> AVCaptureDevice { switch self { case .front: - guard let devices = AVCaptureDeviceDiscoverySession(deviceTypes: [], mediaType: AVMediaTypeVideo, position: .front).devices else {break} + let devices = AVCaptureDevice.DiscoverySession(deviceTypes: [], mediaType: .video, position: .front).devices print("devices:\(devices)") for device in devices where device.position == .front { return device @@ -23,6 +23,6 @@ enum CameraType : Int { default: break } - return AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) + return AVCaptureDevice.default(for: .video)! } } diff --git a/libs/VideoCapture/VideoCapture.swift b/libs/VideoCapture/VideoCapture.swift index 778bfba..b3c130a 100644 --- a/libs/VideoCapture/VideoCapture.swift +++ b/libs/VideoCapture/VideoCapture.swift @@ -34,7 +34,7 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa // setup video format do { - captureSession.sessionPreset = AVCaptureSessionPresetInputPriority + captureSession.sessionPreset = AVCaptureSession.Preset.inputPriority if let preferredSpec = preferredSpec { // update the format with a preferred fps videoDevice.updateFormatWithPreferredVideoSpec(preferredSpec: preferredSpec) @@ -58,7 +58,7 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa // setup audio device input do { - let audioDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) + guard let audioDevice = AVCaptureDevice.default(for: .audio) else {fatalError()} let audioDeviceInput: AVCaptureDeviceInput do { audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice) @@ -74,10 +74,10 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa // setup preview if let previewContainer = previewContainer { - guard let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) else {fatalError()} + let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer.frame = previewContainer.bounds previewLayer.contentsGravity = kCAGravityResizeAspectFill - previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill + previewLayer.videoGravity = .resizeAspectFill previewContainer.insertSublayer(previewLayer, at: 0) self.previewLayer = previewLayer } @@ -85,7 +85,7 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa // setup video output do { let videoDataOutput = AVCaptureVideoDataOutput() - videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable: NSNumber(value: kCVPixelFormatType_32BGRA)] + videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable as! String: NSNumber(value: kCVPixelFormatType_32BGRA)] videoDataOutput.alwaysDiscardsLateVideoFrames = true let queue = DispatchQueue(label: "com.shu223.videosamplequeue") videoDataOutput.setSampleBufferDelegate(self, queue: queue) @@ -94,7 +94,7 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa } captureSession.addOutput(videoDataOutput) - videoConnection = videoDataOutput.connection(withMediaType: AVMediaTypeVideo) + videoConnection = videoDataOutput.connection(with: .video) } // setup audio output @@ -107,7 +107,7 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa } captureSession.addOutput(audioDataOutput) - audioConnection = audioDataOutput.connection(withMediaType: AVMediaTypeAudio) + audioConnection = audioDataOutput.connection(with: .audio) } // setup asset writer @@ -151,12 +151,11 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa // ========================================================================= // MARK: - AVCaptureVideoDataOutputSampleBufferDelegate - func captureOutput(_ captureOutput: AVCaptureOutput!, didDrop sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { + func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { // print("\(self.classForCoder)/" + #function) } - - func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) - { + + func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { // FIXME: temp if connection.videoOrientation != .portrait { connection.videoOrientation = .portrait From 2260235645b4d3c322671f2eae1d8411be982dcb Mon Sep 17 00:00:00 2001 From: Shuichi Tsutsumi Date: Mon, 2 Oct 2017 23:07:50 -0500 Subject: [PATCH 06/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d3ff37..5a2702f 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ Haptic Feedbacks using UIFeedbackGenerator. Freelance iOS programmer in Japan. - PAST WORKS: [My Profile Summary](https://medium.com/@shu223/my-profile-summary-f14bfc1e7099#.vdh0i7clr) -- PROFILES: [LinkedIn](https://www.linkedin.com/profile/view?id=214896557) +- PROFILES: [LinkedIn](https://www.linkedin.com/in/shuichi-tsutsumi-525b755b/) - BLOGS: [English](https://medium.com/@shu223/) / [Japanese](http://d.hatena.ne.jp/shu223/) - CONTACTS: [Twitter](https://twitter.com/shu223) / [Facebook](https://www.facebook.com/shuichi.tsutsumi) From 7b134cd8d0bb8494450350cd6d2c253356aa58bc Mon Sep 17 00:00:00 2001 From: shu223 Date: Mon, 4 Dec 2017 08:28:28 +0900 Subject: [PATCH 07/23] Added 1024x1024 icon --- .../AppIcon.appiconset/10-iTunesArtwork.png | Bin 0 -> 170981 bytes .../AppIcon.appiconset/Contents.json | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 iOS-10-Sampler/Assets.xcassets/AppIcon.appiconset/10-iTunesArtwork.png diff --git a/iOS-10-Sampler/Assets.xcassets/AppIcon.appiconset/10-iTunesArtwork.png b/iOS-10-Sampler/Assets.xcassets/AppIcon.appiconset/10-iTunesArtwork.png new file mode 100644 index 0000000000000000000000000000000000000000..8c03172d6cff74f4504f605d45c183d78314566e GIT binary patch literal 170981 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 Jm8 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 Date: Mon, 4 Dec 2017 08:28:59 +0900 Subject: [PATCH 08/23] Solved a warning --- iOS-10-Sampler/Samples/AttributedSpeechViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift b/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift index c249070..d8e6f81 100644 --- a/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift +++ b/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift @@ -22,7 +22,7 @@ class AttributedSpeechViewController: UIViewController { super.viewDidLoad() attributedStr = NSMutableAttributedString(string: baseStr) - let rangeAll = NSMakeRange(0, baseStr.characters.count) + let rangeAll = NSMakeRange(0, baseStr.count) let rangeBold = NSString(string: baseStr).range(of: "iOS") attributedStr.addAttributes([NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14)], range: rangeAll) attributedStr.addAttributes([NSAttributedStringKey.foregroundColor: UIColor.black], range: rangeAll) From 5dc3a9ee2d7f8d486a868fd5eda64f0855de7793 Mon Sep 17 00:00:00 2001 From: shu223 Date: Mon, 4 Dec 2017 08:31:14 +0900 Subject: [PATCH 09/23] Fixed a warning for an autolayout setting in the Main.storyboard --- iOS-10-Sampler/Base.lproj/Main.storyboard | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/iOS-10-Sampler/Base.lproj/Main.storyboard b/iOS-10-Sampler/Base.lproj/Main.storyboard index 7c49b02..5ba2877 100644 --- a/iOS-10-Sampler/Base.lproj/Main.storyboard +++ b/iOS-10-Sampler/Base.lproj/Main.storyboard @@ -1,8 +1,11 @@ - - + + + + + - + @@ -17,18 +20,20 @@ - + - + @@ -65,7 +71,7 @@ - + From f206fbb1906a8b28d11cfa0886de08af1c83c70f Mon Sep 17 00:00:00 2001 From: shu223 Date: Thu, 10 May 2018 20:07:11 -0700 Subject: [PATCH 10/23] added by Xcode 9.3 --- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 iOS-10-Sampler.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/iOS-10-Sampler.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/iOS-10-Sampler.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/iOS-10-Sampler.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + From 0ad2d17f58afcb79ca4f74079f4ce171eb862567 Mon Sep 17 00:00:00 2001 From: shu223 Date: Sat, 9 Jun 2018 15:48:58 -0700 Subject: [PATCH 11/23] Fixed the Attributed Speech sample --- README.md | 9 ++++----- .../Samples/AttributedSpeechViewController.swift | 10 +++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5a2702f..738b62b 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Live Photo Capturing example using AVCapturePhotoOutput. ### Audio Fade-in/out -Audio fade-in/out demo using `setVolume:fadeDuration` method which is added to AVAudioPlayer. +Audio fade-in/out demo using `setVolume:fadeDuration` method which is added to `AVAudioPlayer`. ### Metal CNN Basic: Digit Detection @@ -58,13 +58,13 @@ Real-time image recognition using CNN (Convolutional Neural Network) by Metal Pe ### PropertyAnimator: Position -Animating UIView's `center` & `backgroundColor` using UIViewPropertyAnimator. +Animating UIView's `center` & `backgroundColor` using `UIViewPropertyAnimator`. ### PropertyAnimator: Blur -Animating blur effect using `fractionComplete` property of UIViewPropertyAnimator. +Animating blur effect using `fractionComplete` property of `UIViewPropertyAnimator`. @@ -121,9 +121,8 @@ This sample demonstrates how to use new `mapItem` property of NSUserActivity to ### Attributed Speech -Attributed Speech demo using `attributedSpeechString` of AVSpeechUtterance. +Attributed Speech demo with `AVSpeechSynthesisIPANotationAttribute` for `AVSpeechUtterance`. -But it seems **NOT** to affect the speech with this attribute. Anyone, please let me know how to use this new API. ### Haptic Feedback diff --git a/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift b/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift index d8e6f81..397cbcf 100644 --- a/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift +++ b/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift @@ -14,7 +14,7 @@ class AttributedSpeechViewController: UIViewController { @IBOutlet private weak var label: UILabel! private let speech = AVSpeechSynthesizer() - private let baseStr = "iOS 10 Sampler is a collection of code examples for new APIs of iOS 10." + private let baseStr = "Tsutsumi" private var attributedStr: NSMutableAttributedString! private var utterance: AVSpeechUtterance! @@ -23,11 +23,7 @@ class AttributedSpeechViewController: UIViewController { attributedStr = NSMutableAttributedString(string: baseStr) let rangeAll = NSMakeRange(0, baseStr.count) - let rangeBold = NSString(string: baseStr).range(of: "iOS") - attributedStr.addAttributes([NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14)], range: rangeAll) - attributedStr.addAttributes([NSAttributedStringKey.foregroundColor: UIColor.black], range: rangeAll) - attributedStr.addAttributes([NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 20)], range: rangeBold) - + attributedStr.addAttribute(NSAttributedStringKey(rawValue: AVSpeechSynthesisIPANotationAttribute), value: "tən.tən.mi", range: rangeAll) updateUtterance(attributed: false) } @@ -38,7 +34,7 @@ class AttributedSpeechViewController: UIViewController { private func updateUtterance(attributed: Bool) { if attributed { utterance = AVSpeechUtterance(attributedString: attributedStr) - label.attributedText = attributedStr + label.text = baseStr + " (attributed)" } else { utterance = AVSpeechUtterance(string: baseStr) label.text = baseStr From a8f5035b5a5322d7c31e93273deb9dd22658bd06 Mon Sep 17 00:00:00 2001 From: shu223 Date: Sat, 9 Jun 2018 16:03:34 -0700 Subject: [PATCH 12/23] Fixed a crashing bug --- .../PropertyAnimatorEffectViewController.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/iOS-10-Sampler/Samples/PropertyAnimatorEffectViewController.swift b/iOS-10-Sampler/Samples/PropertyAnimatorEffectViewController.swift index 67209ee..91d8e30 100644 --- a/iOS-10-Sampler/Samples/PropertyAnimatorEffectViewController.swift +++ b/iOS-10-Sampler/Samples/PropertyAnimatorEffectViewController.swift @@ -18,12 +18,20 @@ class PropertyAnimatorEffectViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) animator = UIViewPropertyAnimator(duration: 0, curve: .linear) { self.effectView.effect = nil } } - + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + animator.startAnimation() + } + override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } From 51b3f93da5ae10b3f7216b70d34922815f1f8053 Mon Sep 17 00:00:00 2001 From: shu223 Date: Sat, 9 Jun 2018 17:14:47 -0700 Subject: [PATCH 13/23] Enable to work with Xcode 9.3, 9.4 / iOS 10 --- iOS-10-Sampler.xcodeproj/project.pbxproj | 132 ++------- .../xcschemes/iOS-10-Sampler.xcscheme | 2 +- iOS-10-Sampler/Samples/Inception3Net.swift | 19 +- .../SlimMPSCNNConvolution.h | 86 ++++++ .../SlimMPSCNNConvolution.m | 255 ++++++++++++++++++ .../SlimMPSCNNFullyConnected.h | 22 ++ .../SlimMPSCNNFullyConnected.m | 78 ++++++ iOS-10-Sampler/iOS10Sampler-Bridging-Header.h | 3 + 8 files changed, 479 insertions(+), 118 deletions(-) create mode 100644 iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNConvolution.h create mode 100644 iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNConvolution.m create mode 100644 iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.h create mode 100644 iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.m diff --git a/iOS-10-Sampler.xcodeproj/project.pbxproj b/iOS-10-Sampler.xcodeproj/project.pbxproj index bd44560..7696bb2 100644 --- a/iOS-10-Sampler.xcodeproj/project.pbxproj +++ b/iOS-10-Sampler.xcodeproj/project.pbxproj @@ -26,7 +26,6 @@ 8A1CC3621D7AAFBC00562709 /* MetalCNNBasicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1CC3611D7AAFBC00562709 /* MetalCNNBasicViewController.swift */; }; 8A1CC3641D7AAFCC00562709 /* MetalCNNBasic.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8A1CC3631D7AAFCC00562709 /* MetalCNNBasic.storyboard */; }; 8A1CC37F1D7AB10D00562709 /* DrawView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1CC37B1D7AB10D00562709 /* DrawView.swift */; }; - 8A1CC3811D7AB10D00562709 /* SlimMPSCNN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1CC37D1D7AB10D00562709 /* SlimMPSCNN.swift */; }; 8A1CC3891D7ABCE400562709 /* MNISTDeepCNN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1CC3881D7ABCE400562709 /* MNISTDeepCNN.swift */; }; 8A1CC38F1D7AC22E00562709 /* Stickers.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8A1CC38E1D7AC22E00562709 /* Stickers.xcassets */; }; 8A1CC3931D7AC22E00562709 /* SamplerStickerPack.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8A1CC38C1D7AC22E00562709 /* SamplerStickerPack.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -242,6 +241,8 @@ 8A5AE0B91D7D50E80095209E /* LivePhotoCapture.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8A5AE0B81D7D50E80095209E /* LivePhotoCapture.storyboard */; }; 8A5AE0BC1D7D58AB0095209E /* LivePhotoCaptureDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A5AE0BB1D7D58AB0095209E /* LivePhotoCaptureDelegate.swift */; }; 8A5AE0BE1D7D61C70095209E /* PreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A5AE0BD1D7D61C70095209E /* PreviewView.swift */; }; + 8A662A7F20CC94CE00EF23A2 /* SlimMPSCNNConvolution.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A662A7D20CC94CE00EF23A2 /* SlimMPSCNNConvolution.m */; }; + 8A662A8220CC955700EF23A2 /* SlimMPSCNNFullyConnected.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A662A8120CC955700EF23A2 /* SlimMPSCNNFullyConnected.m */; }; 8A6CE2EC1D854B9E00DC79B4 /* LivePhotoCaptureSessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A6CE2EB1D854B9E00DC79B4 /* LivePhotoCaptureSessionManager.swift */; }; 8A736F161D7A892D00A58684 /* AudioFadeInOutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A736F151D7A892D00A58684 /* AudioFadeInOutViewController.swift */; }; 8A736F181D7A893A00A58684 /* AudioFadeInOut.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8A736F171D7A893A00A58684 /* AudioFadeInOut.storyboard */; }; @@ -264,7 +265,6 @@ 8AB430601D7A6B4900A3BD98 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8AB4305F1D7A6B4900A3BD98 /* Assets.xcassets */; }; 8AB430631D7A6B4900A3BD98 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8AB430611D7A6B4900A3BD98 /* LaunchScreen.storyboard */; }; 8AB4306E1D7A6B4A00A3BD98 /* iOS_10_SamplerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB4306D1D7A6B4A00A3BD98 /* iOS_10_SamplerTests.swift */; }; - 8AB430791D7A6B4A00A3BD98 /* iOS_10_SamplerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB430781D7A6B4A00A3BD98 /* iOS_10_SamplerUITests.swift */; }; 8AB430871D7A6DA700A3BD98 /* RootViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB430861D7A6DA700A3BD98 /* RootViewCell.swift */; }; 8AB430891D7A6DF300A3BD98 /* SampleDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB430881D7A6DF300A3BD98 /* SampleDataSource.swift */; }; 8ACF88331E1B8F7C00E1555B /* HapticViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ACF88321E1B8F7C00E1555B /* HapticViewController.swift */; }; @@ -291,13 +291,6 @@ remoteGlobalIDString = 8AB430541D7A6B4900A3BD98; remoteInfo = "iOS-10-Sampler"; }; - 8AB430751D7A6B4A00A3BD98 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8AB4304D1D7A6B4900A3BD98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8AB430541D7A6B4900A3BD98; - remoteInfo = "iOS-10-Sampler"; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -333,7 +326,6 @@ 8A1CC3611D7AAFBC00562709 /* MetalCNNBasicViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalCNNBasicViewController.swift; sourceTree = ""; }; 8A1CC3631D7AAFCC00562709 /* MetalCNNBasic.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MetalCNNBasic.storyboard; sourceTree = ""; }; 8A1CC37B1D7AB10D00562709 /* DrawView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DrawView.swift; path = MetalCNNBasicApple/DrawView.swift; sourceTree = ""; }; - 8A1CC37D1D7AB10D00562709 /* SlimMPSCNN.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SlimMPSCNN.swift; sourceTree = ""; }; 8A1CC3851D7AB15B00562709 /* iOS10Sampler-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iOS10Sampler-Bridging-Header.h"; sourceTree = ""; }; 8A1CC3881D7ABCE400562709 /* MNISTDeepCNN.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MNISTDeepCNN.swift; sourceTree = ""; }; 8A1CC38C1D7AC22E00562709 /* SamplerStickerPack.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SamplerStickerPack.appex; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -552,6 +544,10 @@ 8A5AE0B81D7D50E80095209E /* LivePhotoCapture.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LivePhotoCapture.storyboard; sourceTree = ""; }; 8A5AE0BB1D7D58AB0095209E /* LivePhotoCaptureDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LivePhotoCaptureDelegate.swift; sourceTree = ""; }; 8A5AE0BD1D7D61C70095209E /* PreviewView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewView.swift; sourceTree = ""; }; + 8A662A7D20CC94CE00EF23A2 /* SlimMPSCNNConvolution.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlimMPSCNNConvolution.m; sourceTree = ""; }; + 8A662A7E20CC94CE00EF23A2 /* SlimMPSCNNConvolution.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlimMPSCNNConvolution.h; sourceTree = ""; }; + 8A662A8020CC955700EF23A2 /* SlimMPSCNNFullyConnected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlimMPSCNNFullyConnected.h; sourceTree = ""; }; + 8A662A8120CC955700EF23A2 /* SlimMPSCNNFullyConnected.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlimMPSCNNFullyConnected.m; sourceTree = ""; }; 8A6CE2EB1D854B9E00DC79B4 /* LivePhotoCaptureSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LivePhotoCaptureSessionManager.swift; sourceTree = ""; }; 8A736F151D7A892D00A58684 /* AudioFadeInOutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AudioFadeInOutViewController.swift; sourceTree = ""; }; 8A736F171D7A893A00A58684 /* AudioFadeInOut.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = AudioFadeInOut.storyboard; sourceTree = ""; }; @@ -579,7 +575,6 @@ 8AB430691D7A6B4A00A3BD98 /* iOS-10-SamplerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "iOS-10-SamplerTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 8AB4306D1D7A6B4A00A3BD98 /* iOS_10_SamplerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOS_10_SamplerTests.swift; sourceTree = ""; }; 8AB4306F1D7A6B4A00A3BD98 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8AB430741D7A6B4A00A3BD98 /* iOS-10-SamplerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "iOS-10-SamplerUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 8AB430781D7A6B4A00A3BD98 /* iOS_10_SamplerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOS_10_SamplerUITests.swift; sourceTree = ""; }; 8AB4307A1D7A6B4A00A3BD98 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8AB430861D7A6DA700A3BD98 /* RootViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootViewCell.swift; sourceTree = ""; }; @@ -608,13 +603,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 8AB430711D7A6B4A00A3BD98 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -696,7 +684,10 @@ 8A1CC3781D7AB10D00562709 /* Common */ = { isa = PBXGroup; children = ( - 8A1CC37D1D7AB10D00562709 /* SlimMPSCNN.swift */, + 8A662A8020CC955700EF23A2 /* SlimMPSCNNFullyConnected.h */, + 8A662A8120CC955700EF23A2 /* SlimMPSCNNFullyConnected.m */, + 8A662A7E20CC94CE00EF23A2 /* SlimMPSCNNConvolution.h */, + 8A662A7D20CC94CE00EF23A2 /* SlimMPSCNNConvolution.m */, ); name = Common; path = MetalCNNBasicApple; @@ -1110,7 +1101,6 @@ children = ( 8AB430551D7A6B4900A3BD98 /* iOS-10-Sampler.app */, 8AB430691D7A6B4A00A3BD98 /* iOS-10-SamplerTests.xctest */, - 8AB430741D7A6B4A00A3BD98 /* iOS-10-SamplerUITests.xctest */, 8A1CC38C1D7AC22E00562709 /* SamplerStickerPack.appex */, ); name = Products; @@ -1252,24 +1242,6 @@ productReference = 8AB430691D7A6B4A00A3BD98 /* iOS-10-SamplerTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 8AB430731D7A6B4A00A3BD98 /* iOS-10-SamplerUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8AB430831D7A6B4A00A3BD98 /* Build configuration list for PBXNativeTarget "iOS-10-SamplerUITests" */; - buildPhases = ( - 8AB430701D7A6B4A00A3BD98 /* Sources */, - 8AB430711D7A6B4A00A3BD98 /* Frameworks */, - 8AB430721D7A6B4A00A3BD98 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 8AB430761D7A6B4A00A3BD98 /* PBXTargetDependency */, - ); - name = "iOS-10-SamplerUITests"; - productName = "iOS-10-SamplerUITests"; - productReference = 8AB430741D7A6B4A00A3BD98 /* iOS-10-SamplerUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1277,7 +1249,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = "Shuichi Tsutsumi"; TargetAttributes = { 8A1CC38B1D7AC22E00562709 = { @@ -1298,13 +1270,6 @@ ProvisioningStyle = Automatic; TestTargetID = 8AB430541D7A6B4900A3BD98; }; - 8AB430731D7A6B4A00A3BD98 = { - CreatedOnToolsVersion = 8.0; - DevelopmentTeam = 9Z86A4AWDE; - LastSwiftMigration = 0900; - ProvisioningStyle = Automatic; - TestTargetID = 8AB430541D7A6B4900A3BD98; - }; }; }; buildConfigurationList = 8AB430501D7A6B4900A3BD98 /* Build configuration list for PBXProject "iOS-10-Sampler" */; @@ -1322,7 +1287,6 @@ targets = ( 8AB430541D7A6B4900A3BD98 /* iOS-10-Sampler */, 8AB430681D7A6B4A00A3BD98 /* iOS-10-SamplerTests */, - 8AB430731D7A6B4A00A3BD98 /* iOS-10-SamplerUITests */, 8A1CC38B1D7AC22E00562709 /* SamplerStickerPack */, ); }; @@ -1574,13 +1538,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 8AB430721D7A6B4A00A3BD98 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1589,6 +1546,7 @@ buildActionMask = 2147483647; files = ( 8A825D521D7AA4E6008D74EA /* AttributedSpeechViewController.swift in Sources */, + 8A662A7F20CC94CE00EF23A2 /* SlimMPSCNNConvolution.m in Sources */, 8AB430871D7A6DA700A3BD98 /* RootViewCell.swift in Sources */, 8A5AE0BC1D7D58AB0095209E /* LivePhotoCaptureDelegate.swift in Sources */, 8A081D131D87394200D7DDF4 /* UIViewController+alert.swift in Sources */, @@ -1609,7 +1567,6 @@ 8A1CC3891D7ABCE400562709 /* MNISTDeepCNN.swift in Sources */, 8C3A5F501D7EF7BE00B7A480 /* Message+CoreDataClass.swift in Sources */, 8A3F09AC1D83F7F700D28DF2 /* FontsViewController.swift in Sources */, - 8A1CC3811D7AB10D00562709 /* SlimMPSCNN.swift in Sources */, 8C67369F1D7EFE7000BAAE02 /* iOS10Sampler.xcdatamodeld in Sources */, 8A6CE2EC1D854B9E00DC79B4 /* LivePhotoCaptureSessionManager.swift in Sources */, 8A081D071D8714C200D7DDF4 /* LooperViewController.swift in Sources */, @@ -1623,6 +1580,7 @@ 8A081D1A1D87932100D7DDF4 /* PreviewInteractionPopViewController.swift in Sources */, 8AB430891D7A6DF300A3BD98 /* SampleDataSource.swift in Sources */, 8A1CC3991D7AC43C00562709 /* StickerPackViewController.swift in Sources */, + 8A662A8220CC955700EF23A2 /* SlimMPSCNNFullyConnected.m in Sources */, 8A49EF461D7BF4D8003EE90B /* UserNotificationViewController.swift in Sources */, 8AA0743F1D86614400FEAC28 /* PropertyAnimatorEffectViewController.swift in Sources */, 8C3A5F521D7EF7BE00B7A480 /* PersistentContainerViewController.swift in Sources */, @@ -1639,14 +1597,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 8AB430701D7A6B4A00A3BD98 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8AB430791D7A6B4A00A3BD98 /* iOS_10_SamplerUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -1660,11 +1610,6 @@ target = 8AB430541D7A6B4900A3BD98 /* iOS-10-Sampler */; targetProxy = 8AB4306A1D7A6B4A00A3BD98 /* PBXContainerItemProxy */; }; - 8AB430761D7A6B4A00A3BD98 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8AB430541D7A6B4900A3BD98 /* iOS-10-Sampler */; - targetProxy = 8AB430751D7A6B4A00A3BD98 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -1724,6 +1669,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; @@ -1731,6 +1677,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; @@ -1780,6 +1727,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; @@ -1787,6 +1735,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; @@ -1826,7 +1775,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Debug; @@ -1841,7 +1790,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Release; @@ -1856,7 +1805,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOS-10-Sampler.app/iOS-10-Sampler"; }; @@ -1872,42 +1821,12 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOS-10-Sampler.app/iOS-10-Sampler"; }; name = Release; }; - 8AB430841D7A6B4A00A3BD98 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - DEVELOPMENT_TEAM = 9Z86A4AWDE; - INFOPLIST_FILE = "iOS-10-SamplerUITests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerUITests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - TEST_TARGET_NAME = "iOS-10-Sampler"; - }; - name = Debug; - }; - 8AB430851D7A6B4A00A3BD98 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - DEVELOPMENT_TEAM = 9Z86A4AWDE; - INFOPLIST_FILE = "iOS-10-SamplerUITests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerUITests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; - SWIFT_VERSION = 4.0; - TEST_TARGET_NAME = "iOS-10-Sampler"; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1947,15 +1866,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 8AB430831D7A6B4A00A3BD98 /* Build configuration list for PBXNativeTarget "iOS-10-SamplerUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8AB430841D7A6B4A00A3BD98 /* Debug */, - 8AB430851D7A6B4A00A3BD98 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ diff --git a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme index d216029..0e6f1bb 100644 --- a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme +++ b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme @@ -1,6 +1,6 @@ +@import MetalPerformanceShaders; + +@interface SlimMPSCNNConvolution : MPSCNNConvolution + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName; + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName +destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset; + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad; + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + strideX:(NSUInteger)strideX + strideY:(NSUInteger)strideY; + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset; + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + strideX:(NSUInteger)strideX + strideY:(NSUInteger)strideY + destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset; + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + strideX:(NSUInteger)strideX + strideY:(NSUInteger)strideY + destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset + groupNum:(NSUInteger)groupNum; + +@end diff --git a/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNConvolution.m b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNConvolution.m new file mode 100644 index 0000000..b512665 --- /dev/null +++ b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNConvolution.m @@ -0,0 +1,255 @@ +// +// SlimMPSCNNConvolution.m +// iOS-10-Sampler +// +// Created by Shuichi Tsutsumi on 6/9/18. +// Copyright © 2018 Shuichi Tsutsumi, Inc. All rights reserved. +// + +#import "SlimMPSCNNConvolution.h" +#include + +// https://forums.developer.apple.com/thread/99554 +@interface MPSCNNConvolution (MPSCNNConvolution_iOS10) + +-(nonnull instancetype) initWithDevice: (nonnull id ) device + convolutionDescriptor: (const MPSCNNConvolutionDescriptor * __nonnull) convolutionDescriptor + kernelWeights: (const float * __nonnull) kernelWeights + biasTerms: (const float * __nullable) biasTerms + flags: (MPSCNNConvolutionFlags) flags; +@end + +@interface SlimMPSCNNConvolution () +{ + BOOL bn; +} +@end + + +@implementation SlimMPSCNNConvolution + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName +{ + return [self initWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter + device:device + kernelParamsBinaryName:kernelParamsBinaryName + padding:YES]; +} + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset +{ + return [self initWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter + device:device + kernelParamsBinaryName:kernelParamsBinaryName + padding:YES + strideX:1 + strideY:1 + destinationFeatureChannelOffset:destinationFeatureChannelOffset]; +} + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad +{ + return [self initWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter + device:device + kernelParamsBinaryName:kernelParamsBinaryName + padding:willPad + strideX:1 + strideY:1]; +} + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + strideX:(NSUInteger)strideX + strideY:(NSUInteger)strideY +{ + return [self initWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter + device:device + kernelParamsBinaryName:kernelParamsBinaryName + padding:willPad + strideX:strideX + strideY:strideY + destinationFeatureChannelOffset:0]; +} + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset +{ + return [self initWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter + device:device + kernelParamsBinaryName:kernelParamsBinaryName + padding:willPad + strideX:1 + strideY:1 + destinationFeatureChannelOffset:destinationFeatureChannelOffset + groupNum:1]; +} + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + strideX:(NSUInteger)strideX + strideY:(NSUInteger)strideY + destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset +{ + return [self initWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter + device:device + kernelParamsBinaryName:kernelParamsBinaryName + padding:willPad + strideX:strideX + strideY:strideY + destinationFeatureChannelOffset:destinationFeatureChannelOffset + groupNum:1]; +} + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName + padding:(BOOL)willPad + strideX:(NSUInteger)strideX + strideY:(NSUInteger)strideY + destinationFeatureChannelOffset:(NSUInteger)destinationFeatureChannelOffset + groupNum:(NSUInteger)groupNum; +{ + // calculate the size of weights and bias required to be memory mapped into memory + NSUInteger sizeBias = outputFeatureChannels * sizeof(float); + NSUInteger sizeWeights = inputFeatureChannels * kernelHeight * kernelWidth * outputFeatureChannels * sizeof(float); + + // get the url to this layer's weights and bias + NSString *filenameW = [NSString stringWithFormat:@"weights_%@", kernelParamsBinaryName]; + NSString *filenameB = [NSString stringWithFormat:@"bias_%@", kernelParamsBinaryName]; + NSString *wtPath = [[NSBundle mainBundle] pathForResource:filenameW ofType:@"dat"]; + NSString *bsPath = [[NSBundle mainBundle] pathForResource:filenameB ofType:@"dat"]; + NSAssert1(wtPath, @"Error: failed to find file %@", filenameW); + NSAssert1(bsPath, @"Error: failed to find file %@", filenameB); + + // open file descriptors in read-only mode to parameter files + int fd_w = open([wtPath UTF8String], O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + int fd_b = open([bsPath UTF8String], O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + NSAssert1(fd_w != -1, @"Error: failed to open output file at %@", wtPath); + NSAssert1(fd_b != -1, @"Error: failed to open output file at %@", bsPath); + + // memory map the parameters + void *hdrW = mmap(nil, sizeWeights, PROT_READ, MAP_FILE | MAP_SHARED, fd_w, 0); + void *hdrB = mmap(nil, sizeBias, PROT_READ, MAP_FILE | MAP_SHARED, fd_b, 0); + + // cast Void pointers to Float + float *w = hdrW; + float *b = hdrB; + + MPSCNNConvolutionDescriptor *convDesc; + convDesc = [MPSCNNConvolutionDescriptor cnnConvolutionDescriptorWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter]; + convDesc.strideInPixelsX = strideX; + convDesc.strideInPixelsY = strideY; + convDesc.groups = groupNum; + + self = [super initWithDevice:device + convolutionDescriptor:convDesc + kernelWeights:w + biasTerms:b + flags:MPSCNNConvolutionFlagsNone]; + + self.destinationFeatureChannelOffset = destinationFeatureChannelOffset; + + // FIXME: - +// self.padding = willPad; + + NSAssert1(munmap(hdrW, sizeWeights) == 0, @"error %s" ,"hdrW"); + NSAssert1(munmap(hdrB, sizeBias) == 0, @"error %s" ,"hdrB"); + + close(fd_w); + close(fd_b); + return self; +} + +- (void)encodeToCommandBuffer:(id)commandBuffer + sourceImage:(MPSImage *)sourceImage + destinationImage:(MPSImage *)destinationImage +{ + // padding + NSUInteger padAlongHeight = (destinationImage.height - 1) * self.strideInPixelsY + self.kernelHeight - sourceImage.height; + NSUInteger padAlongWidth = (destinationImage.width - 1) *self.strideInPixelsX + self.kernelWidth - sourceImage.width; + NSUInteger padTop = padAlongHeight / 2; + NSUInteger padLeft = padAlongWidth / 2; + MPSOffset offset; + offset.x = self.kernelWidth/2 - padLeft; + offset.y = self.kernelHeight/2 - padTop; + offset.z = 0; + self.offset = offset; + + [super encodeToCommandBuffer:commandBuffer + sourceImage:sourceImage + destinationImage:destinationImage]; + +} + +@end diff --git a/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.h b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.h new file mode 100644 index 0000000..d7186ff --- /dev/null +++ b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.h @@ -0,0 +1,22 @@ +// +// SlimMPSCNNFullyConnected.h +// iOS-10-Sampler +// +// Created by Shuichi Tsutsumi on 6/9/18. +// Copyright © 2018 Shuichi Tsutsumi, Inc. All rights reserved. +// + +#import +@import MetalPerformanceShaders; + +@interface SlimMPSCNNFullyConnected : MPSCNNFullyConnected + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName; + +@end diff --git a/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.m b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.m new file mode 100644 index 0000000..8e5a2c0 --- /dev/null +++ b/iOS-10-Sampler/Samples/MetalCNNBasicApple/SlimMPSCNNFullyConnected.m @@ -0,0 +1,78 @@ +// +// SlimMPSCNNFullyConnected.m +// iOS-10-Sampler +// +// Created by Shuichi Tsutsumi on 6/9/18. +// Copyright © 2018 Shuichi Tsutsumi, Inc. All rights reserved. +// + +#import "SlimMPSCNNFullyConnected.h" +#include + +@interface SlimMPSCNNFullyConnected () +{ + BOOL bn; +} +@end + + +@implementation SlimMPSCNNFullyConnected + +- (instancetype)initWithKernelWidth:(NSUInteger)kernelWidth + kernelHeight:(NSUInteger)kernelHeight + inputFeatureChannels:(NSUInteger)inputFeatureChannels + outputFeatureChannels:(NSUInteger)outputFeatureChannels + neuronFilter:(MPSCNNNeuron *)neuronFilter + device:(id)device + kernelParamsBinaryName:(NSString *)kernelParamsBinaryName +{ + // calculate the size of weights and bias required to be memory mapped into memory + NSUInteger sizeBias = outputFeatureChannels * sizeof(float); + NSUInteger sizeWeights = inputFeatureChannels * kernelHeight * kernelWidth * outputFeatureChannels * sizeof(float); + + // get the url to this layer's weights and bias + NSString *filenameW = [NSString stringWithFormat:@"weights_%@", kernelParamsBinaryName]; + NSString *filenameB = [NSString stringWithFormat:@"bias_%@", kernelParamsBinaryName]; + NSString *wtPath = [[NSBundle mainBundle] pathForResource:filenameW ofType:@"dat"]; + NSString *bsPath = [[NSBundle mainBundle] pathForResource:filenameB ofType:@"dat"]; + NSAssert1(wtPath, @"Error: failed to find file %@", filenameW); + NSAssert1(bsPath, @"Error: failed to find file %@", filenameB); + + // open file descriptors in read-only mode to parameter files + int fd_w = open([wtPath UTF8String], O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + int fd_b = open([bsPath UTF8String], O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + NSAssert1(fd_w != -1, @"Error: failed to open output file at %@", wtPath); + NSAssert1(fd_b != -1, @"Error: failed to open output file at %@", bsPath); + + // memory map the parameters + void *hdrW = mmap(nil, sizeWeights, PROT_READ, MAP_FILE | MAP_SHARED, fd_w, 0); + void *hdrB = mmap(nil, sizeBias, PROT_READ, MAP_FILE | MAP_SHARED, fd_b, 0); + + // cast Void pointers to Float + float *w = hdrW; + float *b = hdrB; + + MPSCNNConvolutionDescriptor *convDesc; + convDesc = [MPSCNNConvolutionDescriptor cnnConvolutionDescriptorWithKernelWidth:kernelWidth + kernelHeight:kernelHeight + inputFeatureChannels:inputFeatureChannels + outputFeatureChannels:outputFeatureChannels + neuronFilter:neuronFilter]; + self = [super initWithDevice:device + convolutionDescriptor:convDesc + kernelWeights:w + biasTerms:b + flags:MPSCNNConvolutionFlagsNone]; + if (self) { + self.destinationFeatureChannelOffset = 0; + } + + NSAssert1(munmap(hdrW, sizeWeights) == 0, @"error %s" ,"hdrW"); + NSAssert1(munmap(hdrB, sizeBias) == 0, @"error %s" ,"hdrB"); + + close(fd_w); + close(fd_b); + return self; +} + +@end diff --git a/iOS-10-Sampler/iOS10Sampler-Bridging-Header.h b/iOS-10-Sampler/iOS10Sampler-Bridging-Header.h index ed666d3..f33e961 100644 --- a/iOS-10-Sampler/iOS10Sampler-Bridging-Header.h +++ b/iOS-10-Sampler/iOS10Sampler-Bridging-Header.h @@ -9,4 +9,7 @@ #ifndef iOS10Sampler_Bridging_Header_h #define iOS10Sampler_Bridging_Header_h +#import "SlimMPSCNNConvolution.h" +#import "SlimMPSCNNFullyConnected.h" + #endif /* iOS10Sampler_Bridging_Header_h */ From d3a7147784490decf33b06ee6beb5c540267ee12 Mon Sep 17 00:00:00 2001 From: shu223 Date: Sat, 15 Sep 2018 11:29:24 +0900 Subject: [PATCH 14/23] Updated README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 738b62b..c051c45 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,10 @@ Haptic Feedbacks using UIFeedbackGenerator. Freelance iOS programmer in Japan. + + Support via PayPal + + - PAST WORKS: [My Profile Summary](https://medium.com/@shu223/my-profile-summary-f14bfc1e7099#.vdh0i7clr) - PROFILES: [LinkedIn](https://www.linkedin.com/in/shuichi-tsutsumi-525b755b/) - BLOGS: [English](https://medium.com/@shu223/) / [Japanese](http://d.hatena.ne.jp/shu223/) From b6a6f1b0fe109bf5807ccbc28833331824c4c73b Mon Sep 17 00:00:00 2001 From: shu223 Date: Sat, 15 Sep 2018 11:31:00 +0900 Subject: [PATCH 15/23] Fixed warnings --- iOS-10-Sampler/Samples/ImageFiltersViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS-10-Sampler/Samples/ImageFiltersViewController.swift b/iOS-10-Sampler/Samples/ImageFiltersViewController.swift index d2171b7..5f01d00 100644 --- a/iOS-10-Sampler/Samples/ImageFiltersViewController.swift +++ b/iOS-10-Sampler/Samples/ImageFiltersViewController.swift @@ -26,7 +26,7 @@ class ImageFiltersViewController: UIViewController, UIPickerViewDataSource, UIPi available_iOS: 10, category: kCICategoryBuiltIn, exceptCategories: [kCICategoryGradient]) - print("filters:\(filters)\n") + print("filters:\(String(describing: filters))") filters.insert("Original", at: 0) } @@ -90,7 +90,7 @@ class ImageFiltersViewController: UIViewController, UIPickerViewDataSource, UIPi guard let cgImage = context.createCGImage(outputImage, from: extent) else {fatalError()} let image = UIImage(cgImage: cgImage, scale: scale, orientation: .up) - print("extent:\(extent), image:\(image), org:\(self.orgImage), scale:\(scale)\n") + print("extent:\(extent), image:\(image), org:\(String(describing: self.orgImage)), scale:\(String(describing: scale))\n") handler(image) } From a53f2162cdfe1e920e777cfdb9cb0c5ae3d1bf89 Mon Sep 17 00:00:00 2001 From: shu223 Date: Thu, 11 Apr 2019 14:19:30 +0900 Subject: [PATCH 16/23] Update project settings with Xcode 10.2 --- iOS-10-Sampler.xcodeproj/project.pbxproj | 6 ++++-- .../shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/iOS-10-Sampler.xcodeproj/project.pbxproj b/iOS-10-Sampler.xcodeproj/project.pbxproj index 7696bb2..fbe0f95 100644 --- a/iOS-10-Sampler.xcodeproj/project.pbxproj +++ b/iOS-10-Sampler.xcodeproj/project.pbxproj @@ -1249,7 +1249,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0940; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "Shuichi Tsutsumi"; TargetAttributes = { 8A1CC38B1D7AC22E00562709 = { @@ -1274,7 +1274,7 @@ }; buildConfigurationList = 8AB430501D7A6B4900A3BD98 /* Build configuration list for PBXProject "iOS-10-Sampler" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -1660,6 +1660,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++"; @@ -1718,6 +1719,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++"; diff --git a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme index 0e6f1bb..52bc738 100644 --- a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme +++ b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme @@ -1,6 +1,6 @@ Date: Thu, 11 Apr 2019 14:26:09 +0900 Subject: [PATCH 17/23] Swift 5 --- iOS-10-Sampler.xcodeproj/project.pbxproj | 16 ++++++---------- iOS-10-Sampler/AppDelegate.swift | 2 +- iOS-10-Sampler/RootViewController.swift | 4 ++-- .../Samples/AttributedSpeechViewController.swift | 2 +- .../Samples/HapticViewController.swift | 4 ++-- .../PersistentContainerViewController.swift | 2 +- .../SpeechRecognitionViewController.swift | 13 ++++++++++--- .../Samples/StickerPackViewController.swift | 7 ++++++- .../Samples/TabBadgeViewController.swift | 14 ++++++++++---- .../Samples/UserNotificationViewController.swift | 10 +++++----- .../VideoCapture/AVCaptureDevice+Extension.swift | 4 ++-- libs/VideoCapture/VideoCapture.swift | 2 +- 12 files changed, 47 insertions(+), 33 deletions(-) diff --git a/iOS-10-Sampler.xcodeproj/project.pbxproj b/iOS-10-Sampler.xcodeproj/project.pbxproj index fbe0f95..a288299 100644 --- a/iOS-10-Sampler.xcodeproj/project.pbxproj +++ b/iOS-10-Sampler.xcodeproj/project.pbxproj @@ -1260,13 +1260,13 @@ 8AB430541D7A6B4900A3BD98 = { CreatedOnToolsVersion = 8.0; DevelopmentTeam = 9Z86A4AWDE; - LastSwiftMigration = 0900; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; 8AB430681D7A6B4A00A3BD98 = { CreatedOnToolsVersion = 8.0; DevelopmentTeam = 9Z86A4AWDE; - LastSwiftMigration = 0900; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; TestTargetID = 8AB430541D7A6B4900A3BD98; }; @@ -1777,8 +1777,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -1792,8 +1791,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -1807,8 +1805,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOS-10-Sampler.app/iOS-10-Sampler"; }; name = Debug; @@ -1823,8 +1820,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOS-10-Sampler.app/iOS-10-Sampler"; }; name = Release; diff --git a/iOS-10-Sampler/AppDelegate.swift b/iOS-10-Sampler/AppDelegate.swift index e126378..f5604dd 100644 --- a/iOS-10-Sampler/AppDelegate.swift +++ b/iOS-10-Sampler/AppDelegate.swift @@ -14,7 +14,7 @@ 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]?) -> Bool { // Override point for customization after application launch. return true } diff --git a/iOS-10-Sampler/RootViewController.swift b/iOS-10-Sampler/RootViewController.swift index d08a65c..ea9af77 100644 --- a/iOS-10-Sampler/RootViewController.swift +++ b/iOS-10-Sampler/RootViewController.swift @@ -39,11 +39,11 @@ class RootViewController: UITableViewController { // MARK: UITableViewDelegate override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return UITableViewAutomaticDimension + return UITableView.automaticDimension } override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { - return UITableViewAutomaticDimension + return UITableView.automaticDimension } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { diff --git a/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift b/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift index 397cbcf..411cc9f 100644 --- a/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift +++ b/iOS-10-Sampler/Samples/AttributedSpeechViewController.swift @@ -23,7 +23,7 @@ class AttributedSpeechViewController: UIViewController { attributedStr = NSMutableAttributedString(string: baseStr) let rangeAll = NSMakeRange(0, baseStr.count) - attributedStr.addAttribute(NSAttributedStringKey(rawValue: AVSpeechSynthesisIPANotationAttribute), value: "tən.tən.mi", range: rangeAll) + attributedStr.addAttribute(NSAttributedString.Key(rawValue: AVSpeechSynthesisIPANotationAttribute), value: "tən.tən.mi", range: rangeAll) updateUtterance(attributed: false) } diff --git a/iOS-10-Sampler/Samples/HapticViewController.swift b/iOS-10-Sampler/Samples/HapticViewController.swift index dd45935..7ed7a70 100644 --- a/iOS-10-Sampler/Samples/HapticViewController.swift +++ b/iOS-10-Sampler/Samples/HapticViewController.swift @@ -25,14 +25,14 @@ class HapticViewController: UIViewController { } @IBAction func impactBtnTapped(_ sender: UIButton) { - guard let style = UIImpactFeedbackStyle(rawValue: sender.tag) else {fatalError()} + guard let style = UIImpactFeedbackGenerator.FeedbackStyle(rawValue: sender.tag) else {fatalError()} impactFeedbacker = UIImpactFeedbackGenerator(style: style) impactFeedbacker.prepare() impactFeedbacker.impactOccurred() } @IBAction func notificationBtnTapped(_ sender: UIButton) { - guard let type = UINotificationFeedbackType(rawValue: sender.tag) else {fatalError()} + guard let type = UINotificationFeedbackGenerator.FeedbackType(rawValue: sender.tag) else {fatalError()} notificationFeedbacker.notificationOccurred(type) } diff --git a/iOS-10-Sampler/Samples/PersistentContainerViewController.swift b/iOS-10-Sampler/Samples/PersistentContainerViewController.swift index ce856b4..b2a448f 100644 --- a/iOS-10-Sampler/Samples/PersistentContainerViewController.swift +++ b/iOS-10-Sampler/Samples/PersistentContainerViewController.swift @@ -88,7 +88,7 @@ class PersitentContainerViewController: UITableViewController { return true } - override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { switch editingStyle { case .delete: delete(at: indexPath.row) diff --git a/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift b/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift index 61594f8..ebce631 100644 --- a/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift +++ b/iOS-10-Sampler/Samples/SpeechRecognitionViewController.swift @@ -59,6 +59,8 @@ class SpeechRecognitionViewController: UIViewController, SFSpeechRecognizerDeleg case .notDetermined: self.recordBtn.isEnabled = false self.recordBtn.setTitle("Speech recognition not yet authorized", for: .disabled) + @unknown default: + fatalError() } } } @@ -82,9 +84,9 @@ class SpeechRecognitionViewController: UIViewController, SFSpeechRecognizerDeleg } let audioSession = AVAudioSession.sharedInstance() - try audioSession.setCategory(AVAudioSessionCategoryRecord) - try audioSession.setMode(AVAudioSessionModeMeasurement) - try audioSession.setActive(true, with: .notifyOthersOnDeactivation) + try audioSession.setCategory(AVAudioSession.Category(rawValue: convertFromAVAudioSessionCategory(AVAudioSession.Category.record))) + try audioSession.setMode(AVAudioSession.Mode.measurement) + try audioSession.setActive(true, options: .notifyOthersOnDeactivation) recognitionRequest = SFSpeechAudioBufferRecognitionRequest() @@ -179,3 +181,8 @@ class SpeechRecognitionViewController: UIViewController, SFSpeechRecognizerDeleg } } } + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertFromAVAudioSessionCategory(_ input: AVAudioSession.Category) -> String { + return input.rawValue +} diff --git a/iOS-10-Sampler/Samples/StickerPackViewController.swift b/iOS-10-Sampler/Samples/StickerPackViewController.swift index 47a9a4c..974c3d2 100644 --- a/iOS-10-Sampler/Samples/StickerPackViewController.swift +++ b/iOS-10-Sampler/Samples/StickerPackViewController.swift @@ -20,7 +20,12 @@ class StickerPackViewController: UIViewController { @IBAction func openBtnTapped(sender: UIButton) { let url = URL(string: "sms:")! - UIApplication.shared.open(url, options: [:], completionHandler: nil) + UIApplication.shared.open(url, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil) } } + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertToUIApplicationOpenExternalURLOptionsKeyDictionary(_ input: [String: Any]) -> [UIApplication.OpenExternalURLOptionsKey: Any] { + return Dictionary(uniqueKeysWithValues: input.map { key, value in (UIApplication.OpenExternalURLOptionsKey(rawValue: key), value)}) +} diff --git a/iOS-10-Sampler/Samples/TabBadgeViewController.swift b/iOS-10-Sampler/Samples/TabBadgeViewController.swift index bef9158..88e1a3d 100644 --- a/iOS-10-Sampler/Samples/TabBadgeViewController.swift +++ b/iOS-10-Sampler/Samples/TabBadgeViewController.swift @@ -27,11 +27,11 @@ class TabBadgeViewController: UIViewController, UITabBarDelegate { shadow.shadowColor = #colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1) shadow.shadowOffset = CGSize(width: 1, height: 1) shadow.shadowBlurRadius = 3 - let attributes: [String : Any] = [NSAttributedStringKey.font.rawValue: UIFont(name: "Menlo-Bold", size: 30)!, - NSAttributedStringKey.foregroundColor.rawValue: #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1), - NSAttributedStringKey.shadow.rawValue: shadow] + let attributes: [String : Any] = [NSAttributedString.Key.font.rawValue: UIFont(name: "Menlo-Bold", size: 30)!, + NSAttributedString.Key.foregroundColor.rawValue: #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1), + NSAttributedString.Key.shadow.rawValue: shadow] // New! - item.setBadgeTextAttributes(attributes, for: .normal) + item.setBadgeTextAttributes(convertToOptionalNSAttributedStringKeyDictionary(attributes), for: .normal) // New! item.badgeColor = UIColor.clear @@ -62,3 +62,9 @@ class TabBadgeViewController: UIViewController, UITabBarDelegate { } } } + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertToOptionalNSAttributedStringKeyDictionary(_ input: [String: Any]?) -> [NSAttributedString.Key: Any]? { + guard let input = input else { return nil } + return Dictionary(uniqueKeysWithValues: input.map { key, value in (NSAttributedString.Key(rawValue: key), value)}) +} diff --git a/iOS-10-Sampler/Samples/UserNotificationViewController.swift b/iOS-10-Sampler/Samples/UserNotificationViewController.swift index dc11ac5..ca1b806 100644 --- a/iOS-10-Sampler/Samples/UserNotificationViewController.swift +++ b/iOS-10-Sampler/Samples/UserNotificationViewController.swift @@ -35,7 +35,7 @@ class UserNotificationViewController: UIViewController, UNUserNotificationCenter // Build content content.title = "iOS-10-Sampler" content.body = "This is the body." - content.sound = UNNotificationSound.default() + content.sound = UNNotificationSound.default content.attachments = [movieAttachment] // Initializa request @@ -67,11 +67,11 @@ class UserNotificationViewController: UIViewController, UNUserNotificationCenter // ========================================================================= // MARK: - UNNotificationCenterDelegate - private func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) { + internal func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) { print("\(self.classForCoder)/" + #function) } - private func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) { + internal func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) { print("\(self.classForCoder)/" + #function) } @@ -88,10 +88,10 @@ class UserNotificationViewController: UIViewController, UNUserNotificationCenter let alert = UIAlertController( title: "Close this app", message: "A local notification has been scheduled. Close this app and wait 10 sec.", - preferredStyle: UIAlertControllerStyle.alert) + preferredStyle: UIAlertController.Style.alert) let okAction = UIAlertAction( title: "OK", - style: UIAlertActionStyle.cancel, + style: UIAlertAction.Style.cancel, handler: nil) alert.addAction(okAction) self.present(alert, animated: true, completion: nil) diff --git a/libs/VideoCapture/AVCaptureDevice+Extension.swift b/libs/VideoCapture/AVCaptureDevice+Extension.swift index b31af77..1b40d99 100644 --- a/libs/VideoCapture/AVCaptureDevice+Extension.swift +++ b/libs/VideoCapture/AVCaptureDevice+Extension.swift @@ -76,8 +76,8 @@ extension AVCaptureDevice { activeFormat = selectedFormat if let preferredFps = preferredSpec.fps { - activeVideoMinFrameDuration = CMTimeMake(1, preferredFps) - activeVideoMaxFrameDuration = CMTimeMake(1, preferredFps) + activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: preferredFps) + activeVideoMaxFrameDuration = CMTimeMake(value: 1, timescale: preferredFps) unlockForConfiguration() } } diff --git a/libs/VideoCapture/VideoCapture.swift b/libs/VideoCapture/VideoCapture.swift index b3c130a..72f77df 100644 --- a/libs/VideoCapture/VideoCapture.swift +++ b/libs/VideoCapture/VideoCapture.swift @@ -76,7 +76,7 @@ class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVCa if let previewContainer = previewContainer { let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer.frame = previewContainer.bounds - previewLayer.contentsGravity = kCAGravityResizeAspectFill + previewLayer.contentsGravity = CALayerContentsGravity.resizeAspectFill previewLayer.videoGravity = .resizeAspectFill previewContainer.insertSublayer(previewLayer, at: 0) self.previewLayer = previewLayer From 632d2b921553f11387b6d0df73e77aad5ac0caaf Mon Sep 17 00:00:00 2001 From: shu223 Date: Thu, 11 Apr 2019 14:31:53 +0900 Subject: [PATCH 18/23] Fix accessing to UI from the background thread --- .../Samples/ImageFiltersViewController.swift | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/iOS-10-Sampler/Samples/ImageFiltersViewController.swift b/iOS-10-Sampler/Samples/ImageFiltersViewController.swift index 5f01d00..01e661b 100644 --- a/iOS-10-Sampler/Samples/ImageFiltersViewController.swift +++ b/iOS-10-Sampler/Samples/ImageFiltersViewController.swift @@ -34,7 +34,7 @@ class ImageFiltersViewController: UIViewController, UIPickerViewDataSource, UIPi super.didReceiveMemoryWarning() } - private func applyFilter(name: String, handler: ((UIImage?) -> Void)) { + private func applyFilter(name: String, size: CGSize, scale: CGFloat, handler: ((UIImage?) -> Void)) { let inputImage = CIImage(image: self.orgImage)! guard let filter = CIFilter(name: name) else {fatalError()} let attributes = filter.attributes @@ -76,20 +76,18 @@ class ImageFiltersViewController: UIViewController, UIPickerViewDataSource, UIPi return } - let size = self.imageView.frame.size var extent = outputImage.extent - let scale: CGFloat! + var imageScale = scale // some outputImage have infinite extents. e.g. CIDroste if extent.isInfinite { - scale = UIScreen.main.scale extent = CGRect(x: 0, y: 0, width: size.width, height: size.height) } else { - scale = extent.size.width / self.orgImage.size.width + imageScale = extent.size.width / self.orgImage.size.width } guard let cgImage = context.createCGImage(outputImage, from: extent) else {fatalError()} - let image = UIImage(cgImage: cgImage, scale: scale, orientation: .up) + let image = UIImage(cgImage: cgImage, scale: imageScale, orientation: .up) print("extent:\(extent), image:\(image), org:\(String(describing: self.orgImage)), scale:\(String(describing: scale))\n") handler(image) @@ -120,9 +118,12 @@ class ImageFiltersViewController: UIViewController, UIPickerViewDataSource, UIPi } indicator.startAnimating() - + + let size = self.imageView.frame.size + let scale = UIScreen.main.scale + DispatchQueue.global(qos: .default).async { - self.applyFilter(name: self.filters[row], handler: { (image) in + self.applyFilter(name: self.filters[row], size: size, scale: scale, handler: { (image) in DispatchQueue.main.async(execute: { self.imageView.image = image self.indicator.stopAnimating() From fe5edf330600433a5f18ed76bdb8ae64cbd923e5 Mon Sep 17 00:00:00 2001 From: shu223 Date: Wed, 25 Mar 2020 11:22:57 +0900 Subject: [PATCH 19/23] Fix an UI access from a background thread --- iOS-10-Sampler/Samples/UserNotificationViewController.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iOS-10-Sampler/Samples/UserNotificationViewController.swift b/iOS-10-Sampler/Samples/UserNotificationViewController.swift index ca1b806..ec18e50 100644 --- a/iOS-10-Sampler/Samples/UserNotificationViewController.swift +++ b/iOS-10-Sampler/Samples/UserNotificationViewController.swift @@ -84,7 +84,10 @@ class UserNotificationViewController: UIViewController, UNUserNotificationCenter UNUserNotificationCenter.current().delegate = self if let error = error { print("error:\(error)") - } else { + return + } + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } let alert = UIAlertController( title: "Close this app", message: "A local notification has been scheduled. Close this app and wait 10 sec.", From a6d2c96350a5c72ee9d3cf941687f00de95c67cb Mon Sep 17 00:00:00 2001 From: Shuichi Tsutsumi Date: Sun, 29 Mar 2020 07:26:18 +0900 Subject: [PATCH 20/23] Create FUNDING.yml --- .github/FUNDING.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..0708076 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: [shu223] +custom: ['https://paypal.me/shu223', 'https://note.com/shu223/m/me1aa6761ab16'] From d379043972cd6d44e8183891c987168f3bb1bc90 Mon Sep 17 00:00:00 2001 From: shu223 Date: Wed, 1 Apr 2020 15:09:41 +0900 Subject: [PATCH 21/23] Fix UI errors --- iOS-10-Sampler/Base.lproj/Main.storyboard | 21 +++++++++---------- .../Samples/AttributedSpeech.storyboard | 15 +++++++------ .../Samples/SpeechRecognition.storyboard | 17 ++++++++------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/iOS-10-Sampler/Base.lproj/Main.storyboard b/iOS-10-Sampler/Base.lproj/Main.storyboard index 5ba2877..a0a4a09 100644 --- a/iOS-10-Sampler/Base.lproj/Main.storyboard +++ b/iOS-10-Sampler/Base.lproj/Main.storyboard @@ -1,12 +1,9 @@ - - - - + + - - + @@ -23,17 +20,20 @@ - + - From 94c7e83db4cdd0bb629c0329848c8e26c3ec7b4e Mon Sep 17 00:00:00 2001 From: shu223 Date: Wed, 11 Aug 2021 11:13:40 +0900 Subject: [PATCH 22/23] Update with Xcode 12.5.1 --- iOS-10-Sampler.xcodeproj/project.pbxproj | 8 ++++--- .../xcschemes/iOS-10-Sampler.xcscheme | 22 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/iOS-10-Sampler.xcodeproj/project.pbxproj b/iOS-10-Sampler.xcodeproj/project.pbxproj index a288299..ae384e0 100644 --- a/iOS-10-Sampler.xcodeproj/project.pbxproj +++ b/iOS-10-Sampler.xcodeproj/project.pbxproj @@ -1249,7 +1249,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1250; ORGANIZATIONNAME = "Shuichi Tsutsumi"; TargetAttributes = { 8A1CC38B1D7AC22E00562709 = { @@ -1681,6 +1681,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -1706,7 +1707,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -1740,6 +1741,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -1759,7 +1761,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; diff --git a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme index 52bc738..204382a 100644 --- a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme +++ b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -49,17 +58,6 @@ - - - - - - Date: Wed, 1 May 2024 10:24:37 +0900 Subject: [PATCH 23/23] Update project settings with Xcode 15.3 --- iOS-10-Sampler.xcodeproj/project.pbxproj | 44 +++++++++++++------ .../xcschemes/iOS-10-Sampler.xcscheme | 2 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/iOS-10-Sampler.xcodeproj/project.pbxproj b/iOS-10-Sampler.xcodeproj/project.pbxproj index ae384e0..2fd4e7e 100644 --- a/iOS-10-Sampler.xcodeproj/project.pbxproj +++ b/iOS-10-Sampler.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -28,7 +28,7 @@ 8A1CC37F1D7AB10D00562709 /* DrawView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1CC37B1D7AB10D00562709 /* DrawView.swift */; }; 8A1CC3891D7ABCE400562709 /* MNISTDeepCNN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1CC3881D7ABCE400562709 /* MNISTDeepCNN.swift */; }; 8A1CC38F1D7AC22E00562709 /* Stickers.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8A1CC38E1D7AC22E00562709 /* Stickers.xcassets */; }; - 8A1CC3931D7AC22E00562709 /* SamplerStickerPack.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8A1CC38C1D7AC22E00562709 /* SamplerStickerPack.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 8A1CC3931D7AC22E00562709 /* SamplerStickerPack.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 8A1CC38C1D7AC22E00562709 /* SamplerStickerPack.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 8A1CC3991D7AC43C00562709 /* StickerPackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1CC3981D7AC43C00562709 /* StickerPackViewController.swift */; }; 8A1CC39B1D7AC44A00562709 /* StickerPack.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8A1CC39A1D7AC44A00562709 /* StickerPack.storyboard */; }; 8A3CD9B01DA539F000039F36 /* bias_conv1.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8A3CD9A81DA539F000039F36 /* bias_conv1.dat */; }; @@ -294,15 +294,15 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 8A1CC3971D7AC22E00562709 /* Embed App Extensions */ = { + 8A1CC3971D7AC22E00562709 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 13; files = ( - 8A1CC3931D7AC22E00562709 /* SamplerStickerPack.appex in Embed App Extensions */, + 8A1CC3931D7AC22E00562709 /* SamplerStickerPack.appex in Embed Foundation Extensions */, ); - name = "Embed App Extensions"; + name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ @@ -1212,7 +1212,7 @@ 8AB430511D7A6B4900A3BD98 /* Sources */, 8AB430521D7A6B4900A3BD98 /* Frameworks */, 8AB430531D7A6B4900A3BD98 /* Resources */, - 8A1CC3971D7AC22E00562709 /* Embed App Extensions */, + 8A1CC3971D7AC22E00562709 /* Embed Foundation Extensions */, ); buildRules = ( ); @@ -1248,8 +1248,9 @@ 8AB4304D1D7A6B4900A3BD98 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 1250; + LastUpgradeCheck = 1530; ORGANIZATIONNAME = "Shuichi Tsutsumi"; TargetAttributes = { 8A1CC38B1D7AC22E00562709 = { @@ -1273,7 +1274,7 @@ }; }; buildConfigurationList = 8AB430501D7A6B4900A3BD98 /* Build configuration list for PBXProject "iOS-10-Sampler" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 12.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -1693,6 +1694,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -1753,6 +1755,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -1764,7 +1767,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -1775,7 +1779,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 9Z86A4AWDE; INFOPLIST_FILE = "iOS-10-Sampler/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; @@ -1789,7 +1796,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 9Z86A4AWDE; INFOPLIST_FILE = "iOS-10-Sampler/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-Sampler"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "iOS-10-Sampler/iOS10Sampler-Bridging-Header.h"; @@ -1804,7 +1814,11 @@ BUNDLE_LOADER = "$(TEST_HOST)"; DEVELOPMENT_TEAM = 9Z86A4AWDE; INFOPLIST_FILE = "iOS-10-SamplerTests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -1819,7 +1833,11 @@ BUNDLE_LOADER = "$(TEST_HOST)"; DEVELOPMENT_TEAM = 9Z86A4AWDE; INFOPLIST_FILE = "iOS-10-SamplerTests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = "com.shu223.iOS-10-SamplerTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme index 204382a..ead9f9a 100644 --- a/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme +++ b/iOS-10-Sampler.xcodeproj/xcuserdata/shuichi.xcuserdatad/xcschemes/iOS-10-Sampler.xcscheme @@ -1,6 +1,6 @@