├── .gitignore ├── .ruby-version ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── MyAction ├── ActionViewController.swift ├── Base.lproj │ └── MainInterface.storyboard └── Info.plist ├── MyAudioUnit ├── AudioUnitViewController.swift ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist ├── MyAudioUnit-Bridging-Header.h ├── MyAudioUnitAudioUnit.h └── MyAudioUnitAudioUnit.m ├── MyAutoFillCredentialProvider ├── Base.lproj │ └── MainInterface.storyboard ├── CredentialProviderViewController.swift ├── Info.plist └── MyAutoFillCredentialProvider.entitlements ├── MyBroadcastUI ├── Base.lproj │ └── MainInterface.storyboard ├── BroadcastViewController.swift └── Info.plist ├── MyBroadcastUpload ├── Info.plist ├── MovieClipHandler.swift └── SampleHandler.swift ├── MyBroadcastUploadUI ├── Base.lproj │ └── MainInterface.storyboard ├── BroadcastViewController.swift └── Info.plist ├── MyCallDirectory ├── CallDirectoryHandler.swift └── Info.plist ├── MyClassKitContextProvider ├── ContextRequestHandler.swift ├── Info.plist └── MyClassKitContextProvider.entitlements ├── MyContentBlocker ├── ContentBlockerRequestHandler.swift ├── Info.plist └── blockerList.json ├── MyCustomKeyboard ├── Info.plist └── KeyboardViewController.swift ├── MyDocumentProvider ├── Base.lproj │ └── MainInterface.storyboard ├── DocumentPickerViewController.swift ├── Info.plist └── MyDocumentProvider.entitlements ├── MyFileProvider ├── FileProviderEnumerator.swift ├── FileProviderExtension.swift ├── FileProviderItem.swift ├── Info.plist └── MyFileProvider.entitlements ├── MyFileProviderUI ├── Base.lproj │ └── MainInterface.storyboard ├── DocumentActionViewController.swift └── Info.plist ├── MyFinderSync ├── FinderSync.swift ├── Info.plist └── MyFinderSync.entitlements ├── MyFramework ├── File.swift ├── Info.plist └── MyFramework.h ├── MyFrameworkTests ├── Info.plist └── MyFrameworkTests.swift ├── MyIntents ├── Info.plist └── IntentHandler.swift ├── MyIntentsUI ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── IntentViewController.swift ├── MyMacAudioUnit ├── AudioUnitViewController.swift ├── Base.lproj │ └── AudioUnitViewController.xib ├── Info.plist ├── MyMacAudioUnit-Bridging-Header.h ├── MyMacAudioUnit.entitlements ├── MyMacAudioUnitAudioUnit.h └── MyMacAudioUnitAudioUnit.m ├── MyMacContentBlocker ├── ContentBlockerRequestHandler.swift ├── Info.plist ├── MyMacContentBlocker.entitlements └── blockerList.json ├── MyMacNetworkAppProxy ├── AppProxyProvider.swift ├── Info.plist └── MyMacNetworkAppProxy.entitlements ├── MyMacNetworkPacketTunnel ├── Info.plist ├── MyMacNetworkPacketTunnel.entitlements └── PacketTunnelProvider.swift ├── MyMacNotificationService ├── Info.plist └── NotificationService.swift ├── MyMacPhotoEditing ├── Base.lproj │ └── PhotoEditingViewController.xib ├── Info.plist ├── MyMacPhotoEditing.entitlements └── PhotoEditingViewController.swift ├── MyMacPhotoProject ├── Base.lproj │ └── PhotoProjectViewController.xib ├── Info.plist ├── MyMacPhotoProject.entitlements └── PhotoProjectViewController.swift ├── MyMacQuickLookPreview ├── Base.lproj │ └── PreviewViewController.xib ├── Info.plist ├── MyMacQuickLookPreview.entitlements └── PreviewViewController.swift ├── MyMacShare ├── Base.lproj │ └── ShareViewController.xib ├── Info.plist ├── MyMacShare.entitlements ├── ShareViewController.swift └── icon.icns ├── MyMacSharedLinks ├── Info.plist ├── MyMacSharedLinks.entitlements └── RequestHandler.swift ├── MyMacSpotlightIndex ├── IndexRequestHandler.swift ├── Info.plist └── MyMacSpotlightIndex.entitlements ├── MyMacToday ├── Base.lproj │ └── TodayViewController.xib ├── Info.plist ├── MyMacToday.entitlements ├── TodayViewController.swift └── en.lproj │ └── InfoPlist.strings ├── MyMaction ├── ActionViewController.swift ├── Base.lproj │ └── ActionViewController.xib ├── Info.plist ├── MyMaction.entitlements └── icon.icns ├── MyMessageFilter ├── Info.plist └── MessageFilterExtension.swift ├── MyMetalLibrary └── MyMetalLibrary.metal ├── MyNetworkAppProxy ├── AppProxyProvider.swift ├── Info.plist └── MyNetworkAppProxy.entitlements ├── MyNetworkDNSProxy ├── DNSProxyProvider.swift ├── Info.plist └── MyNetworkDNSProxy.entitlements ├── MyNetworkFilterControl ├── FilterControlProvider.swift ├── Info.plist └── MyNetworkFilterControl.entitlements ├── MyNetworkFilterData ├── FilterDataProvider.swift ├── Info.plist └── MyNetworkFilterData.entitlements ├── MyNetworkPacketTunnel ├── Info.plist ├── MyNetworkPacketTunnel.entitlements └── PacketTunnelProvider.swift ├── MyNotificationContent ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── NotificationViewController.swift ├── MyNotificationService ├── Info.plist └── NotificationService.swift ├── MyPhotoEditing ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── PhotoEditingViewController.swift ├── MyQuickLookPreview ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── PreviewViewController.swift ├── MySafariExtension ├── Base.lproj │ └── SafariExtensionViewController.xib ├── Info.plist ├── MySafariExtension.entitlements ├── SafariExtensionHandler.swift ├── SafariExtensionViewController.swift ├── ToolbarItemIcon.pdf └── script.js ├── MyShare ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── ShareViewController.swift ├── MySmartCardToken ├── Info.plist ├── MySmartCardToken.entitlements ├── Token.swift ├── TokenDriver.swift └── TokenSession.swift ├── MySpotlightIndex ├── IndexRequestHandler.swift └── Info.plist ├── MyStaticLibrary ├── MyStaticLibrary.h └── MyStaticLibrary.m ├── MyTVBroadcastUI ├── Base.lproj │ └── MainInterface.storyboard ├── BroadcastViewController.swift └── Info.plist ├── MyTVBroadcastUpload ├── Info.plist ├── MovieClipHandler.swift └── SampleHandler.swift ├── MyTVBroadcastUploadUI ├── Base.lproj │ └── MainInterface.storyboard ├── BroadcastViewController.swift └── Info.plist ├── MyTVServices ├── Info.plist └── ServiceProvider.swift ├── MyThumbnail ├── Info.plist └── ThumbnailProvider.swift ├── MyToday ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── TodayViewController.swift ├── MyUnwantedCommunication ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── UnwantedCommunicationReportingExtension.swift ├── MyWatchIntents ├── Info.plist └── IntentHandler.swift ├── MyXcodeSourceEditor ├── Info.plist ├── MyXcodeSourceEditor.entitlements ├── SourceEditorCommand.swift └── SourceEditorExtension.swift ├── MyiMessage ├── Assets.xcassets │ ├── Contents.json │ └── iMessage App Icon.stickersiconset │ │ └── Contents.json ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── MessagesViewController.swift ├── README.md ├── Scanfile ├── Turducken.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── xcshareddata │ └── xcschemes │ ├── MyAction.xcscheme │ ├── MyAudioUnit.xcscheme │ ├── MyAutoFillCredentialProvider.xcscheme │ ├── MyBroadcastUI.xcscheme │ ├── MyBroadcastUpload.xcscheme │ ├── MyBroadcastUploadUI.xcscheme │ ├── MyCallDirectory.xcscheme │ ├── MyClassKitContextProvider.xcscheme │ ├── MyContentBlocker.xcscheme │ ├── MyCustomKeyboard.xcscheme │ ├── MyDocumentProvider.xcscheme │ ├── MyDocumentProviderFileProvider.xcscheme │ ├── MyFileProvider.xcscheme │ ├── MyFileProviderUI.xcscheme │ ├── MyFinderSync.xcscheme │ ├── MyFramework-macOS.xcscheme │ ├── MyFramework-tvOS.xcscheme │ ├── MyFramework-watchOS.xcscheme │ ├── MyFramework.xcscheme │ ├── MyIntents.xcscheme │ ├── MyIntentsUI.xcscheme │ ├── MyMacAudioUnit.xcscheme │ ├── MyMacContentBlocker.xcscheme │ ├── MyMacNetworkAppProxy.xcscheme │ ├── MyMacNetworkPacketTunnel.xcscheme │ ├── MyMacNotificationService.xcscheme │ ├── MyMacPhotoEditing.xcscheme │ ├── MyMacPhotoProject.xcscheme │ ├── MyMacQuickLookPreview.xcscheme │ ├── MyMacShare.xcscheme │ ├── MyMacSharedLinks.xcscheme │ ├── MyMacSpotlightIndex.xcscheme │ ├── MyMacToday.xcscheme │ ├── MyMaction.xcscheme │ ├── MyMessageFilter.xcscheme │ ├── MyMetalLibrary-macOS.xcscheme │ ├── MyMetalLibrary-tvOS.xcscheme │ ├── MyMetalLibrary.xcscheme │ ├── MyNetworkAppProxy.xcscheme │ ├── MyNetworkDNSProxy.xcscheme │ ├── MyNetworkFilterControl.xcscheme │ ├── MyNetworkFilterData.xcscheme │ ├── MyNetworkPacketTunnel.xcscheme │ ├── MyNotificationContent.xcscheme │ ├── MyNotificationService.xcscheme │ ├── MyPhotoEditing.xcscheme │ ├── MyQuickLookPreview.xcscheme │ ├── MySafariExtension.xcscheme │ ├── MyShare.xcscheme │ ├── MySharedLinks.xcscheme │ ├── MySmartCardToken.xcscheme │ ├── MySpotlightIndex.xcscheme │ ├── MyTVBroadcastUI.xcscheme │ ├── MyTVBroadcastUpload.xcscheme │ ├── MyTVBroadcastUploadUI.xcscheme │ ├── MyTVServices.xcscheme │ ├── MyThumbnail.xcscheme │ ├── MyToday.xcscheme │ ├── MyUnwantedCommunication.xcscheme │ ├── MyWatchIntents.xcscheme │ ├── MyXcodeSourceEditor.xcscheme │ ├── MyiMessage.xcscheme │ ├── TurduckenMac.xcscheme │ ├── TurduckenTV.xcscheme │ ├── TurduckenWatch (Complication).xcscheme │ ├── TurduckenWatch (Notification).xcscheme │ ├── TurduckenWatch.xcscheme │ ├── TurduckeniOS-no-UI-tests.xcscheme │ └── TurduckeniOS.xcscheme ├── Turducken ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── TurduckenMac ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── TurduckenMacTests ├── Info.plist └── TurduckenMacTests.swift ├── TurduckenMacUITests ├── Info.plist └── TurduckenMacUITests.swift ├── TurduckenTV ├── AppDelegate.swift ├── Assets.xcassets │ ├── App Icon & Top Shelf Image.brandassets │ │ ├── App Icon - Large.imagestack │ │ │ ├── Back.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Front.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ └── Middle.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ ├── App Icon - Small.imagestack │ │ │ ├── Back.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Front.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ └── Middle.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Top Shelf Image Wide.imageset │ │ │ └── Contents.json │ │ └── Top Shelf Image.imageset │ │ │ └── Contents.json │ ├── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── TurduckenTVTests ├── Info.plist └── TurduckenTVTests.swift ├── TurduckenTVUITests ├── Info.plist └── TurduckenTVUITests.swift ├── TurduckenTests ├── Info.plist └── TurduckenTests.swift ├── TurduckenUITests ├── Info.plist └── TurduckenUITests.swift ├── TurduckenWatch Extension ├── Assets.xcassets │ └── Complication.complicationset │ │ ├── Circular.imageset │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Extra Large.imageset │ │ └── Contents.json │ │ ├── Modular.imageset │ │ └── Contents.json │ │ └── Utilitarian.imageset │ │ └── Contents.json ├── ComplicationController.swift ├── ExtensionDelegate.swift ├── Info.plist ├── InterfaceController.swift ├── NotificationController.swift └── PushNotificationPayload.apns └── TurduckenWatch ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── Base.lproj └── Interface.storyboard └── Info.plist /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | .DS_Store 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData/ 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata/ 21 | 22 | ## Other 23 | *.moved-aside 24 | *.xcuserstate 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | *.dSYM.zip 30 | *.dSYM 31 | 32 | ## Playgrounds 33 | timeline.xctimeline 34 | playground.xcworkspace 35 | 36 | # Swift Package Manager 37 | # 38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 39 | # Packages/ 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | # Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | # Carthage/Checkouts 54 | 55 | Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots 67 | fastlane/test_output 68 | test_output 69 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.0 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'fastlane' 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jeff Kelley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MyAction/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyAction 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | NSExtensionActivationRule 28 | NSExtensionActivationSupportsText 29 | 30 | NSExtensionMainStoryboard 31 | MainInterface 32 | NSExtensionPointIdentifier 33 | com.apple.ui-services 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /MyAudioUnit/AudioUnitViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioUnitViewController.swift 3 | // MyAudioUnit 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import CoreAudioKit 10 | 11 | public class AudioUnitViewController: AUViewController, AUAudioUnitFactory { 12 | var audioUnit: AUAudioUnit? 13 | 14 | public override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | if audioUnit == nil { 18 | return 19 | } 20 | 21 | // Get the parameter tree and add observers for any parameters that the UI needs to keep in sync with the AudioUnit 22 | } 23 | 24 | public func createAudioUnit(with componentDescription: AudioComponentDescription) throws -> AUAudioUnit { 25 | audioUnit = try MyAudioUnitAudioUnit(componentDescription: componentDescription, options: []) 26 | 27 | return audioUnit! 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /MyAudioUnit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyAudioUnit 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | AudioComponents 28 | 29 | 30 | description 31 | MyAudioUnit 32 | factoryFunction 33 | $(PRODUCT_MODULE_NAME).AudioUnitViewController 34 | manufacturer 35 | JKJK 36 | name 37 | JKJK: MyAudioUnit 38 | sandboxSafe 39 | 40 | subtype 41 | clst 42 | tags 43 | 44 | Synthesizer 45 | 46 | type 47 | aumu 48 | version 49 | 67072 50 | 51 | 52 | 53 | NSExtensionMainStoryboard 54 | MainInterface 55 | NSExtensionPointIdentifier 56 | com.apple.AudioUnit-UI 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /MyAudioUnit/MyAudioUnit-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyAudioUnit-Bridging-Header.h 3 | // MyAudioUnit 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #import "MyAudioUnitAudioUnit.h" 10 | -------------------------------------------------------------------------------- /MyAudioUnit/MyAudioUnitAudioUnit.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyAudioUnitAudioUnit.h 3 | // MyAudioUnit 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // Define parameter addresses. 12 | extern const AudioUnitParameterID myParam1; 13 | 14 | @interface MyAudioUnitAudioUnit : AUAudioUnit 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MyAutoFillCredentialProvider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyAutoFillCredentialProvider 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionMainStoryboard 26 | MainInterface 27 | NSExtensionPointIdentifier 28 | com.apple.authentication-services-credential-provider-ui 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyAutoFillCredentialProvider/MyAutoFillCredentialProvider.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.authentication-services.autofill-credential-provider 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MyBroadcastUI/BroadcastViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BroadcastViewController.swift 3 | // MyBroadcastUI 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import ReplayKit 10 | 11 | class BroadcastViewController: UIViewController { 12 | 13 | // Called when the user has finished interacting with the view controller and a broadcast stream can start 14 | func userDidFinishSetup() { 15 | // Broadcast url that will be returned to the application 16 | let broadcastURL = URL(string:"http://broadcastURL_example/stream1") 17 | 18 | // Service specific broadcast data example which will be supplied to the process extension during broadcast 19 | let userID = "user1" 20 | let endpointURL = "http://broadcastURL_example/stream1/upload" 21 | let setupInfo: [String: NSCoding & NSObjectProtocol] = [ "userID" : userID as NSString, "endpointURL" : endpointURL as NSString ] 22 | 23 | // Set broadcast settings 24 | let broadcastConfiguration = RPBroadcastConfiguration() 25 | broadcastConfiguration.clipDuration = 5 26 | 27 | // Tell ReplayKit that the extension is finished setting up and can begin broadcasting 28 | self.extensionContext?.completeRequest(withBroadcast: broadcastURL!, broadcastConfiguration: broadcastConfiguration, setupInfo: setupInfo) 29 | } 30 | 31 | func userDidCancelSetup() { 32 | let error = NSError(domain: "YouAppDomain", code: -1, userInfo: nil) 33 | // Tell ReplayKit that the extension was cancelled by the user 34 | self.extensionContext?.cancelRequest(withError: error) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MyBroadcastUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyBroadcastUI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | NSExtensionActivationRule 28 | 29 | NSExtensionActivationSupportsReplayKitStreaming 30 | 31 | 32 | 33 | NSExtensionMainStoryboard 34 | MainInterface 35 | NSExtensionPointIdentifier 36 | com.apple.broadcast-services 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /MyBroadcastUpload/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyBroadcastUpload 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.broadcast-services 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).MovieClipHandler 29 | RPBroadcastProcessMode 30 | RPBroadcastProcessModeMP4Clip 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /MyBroadcastUpload/MovieClipHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MovieClipHandler.swift 3 | // MyBroadcastUpload 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import ReplayKit 11 | 12 | class MovieClipHandler: RPBroadcastMP4ClipHandler { 13 | 14 | override func processMP4Clip(with mp4ClipURL: URL?, setupInfo: [String : NSObject]?, finished: Bool) { 15 | // Get the endpoint url supplied by the UI extension in the service info dictionary 16 | let url = URL(string: setupInfo!["endpointURL"] as! String) 17 | 18 | // Set up the request 19 | var request = URLRequest(url: url!) 20 | request.httpMethod = "POST" 21 | 22 | // Upload the movie file with an upload task 23 | let session = URLSession.shared 24 | let uploadTask = session.uploadTask(with: request, fromFile: url!) { (data, response, error) in 25 | if (error != nil) { 26 | // Handle error locally 27 | } 28 | 29 | // Update broadcast settings if necessary 30 | let broadcastConfiguration = RPBroadcastConfiguration() 31 | broadcastConfiguration.clipDuration = 5 32 | 33 | // Tell ReplayKit that processing is complete for thie clip 34 | self.finishedProcessingMP4Clip(withUpdatedBroadcastConfiguration: broadcastConfiguration, error: nil) 35 | } 36 | 37 | uploadTask.resume() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MyBroadcastUpload/SampleHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SampleHandler.swift 3 | // MyBroadcastUpload 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import ReplayKit 10 | 11 | // To handle samples with a subclass of RPBroadcastSampleHandler set the following in the extension's Info.plist file: 12 | // - RPBroadcastProcessMode should be set to RPBroadcastProcessModeSampleBuffer 13 | // - NSExtensionPrincipalClass should be set to this class 14 | 15 | class SampleHandler: RPBroadcastSampleHandler { 16 | 17 | override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) { 18 | // User has requested to start the broadcast. Setup info from the UI extension will be supplied. 19 | } 20 | 21 | override func broadcastPaused() { 22 | // User has requested to pause the broadcast. Samples will stop being delivered. 23 | } 24 | 25 | override func broadcastResumed() { 26 | // User has requested to resume the broadcast. Samples delivery will resume. 27 | } 28 | 29 | override func broadcastFinished() { 30 | // User has requested to finish the broadcast. 31 | } 32 | 33 | override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { 34 | switch sampleBufferType { 35 | case RPSampleBufferType.video: 36 | // Handle audio sample buffer 37 | break 38 | case RPSampleBufferType.audioApp: 39 | // Handle audio sample buffer for app audio 40 | break 41 | case RPSampleBufferType.audioMic: 42 | // Handle audio sample buffer for mic audio 43 | break 44 | @unknown default: 45 | fatalError() 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MyBroadcastUploadUI/BroadcastViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BroadcastViewController.swift 3 | // MyBroadcastUploadUI 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import ReplayKit 10 | 11 | class BroadcastViewController: UIViewController { 12 | 13 | // Called when the user has finished interacting with the view controller and a broadcast stream can start 14 | func userDidFinishSetup() { 15 | // Broadcast url that will be returned to the application 16 | let broadcastURL = URL(string:"http://broadcastURL_example/stream1") 17 | 18 | // Service specific broadcast data example which will be supplied to the process extension during broadcast 19 | let userID = "user1" 20 | let endpointURL = "http://broadcastURL_example/stream1/upload" 21 | let setupInfo: [String: NSCoding & NSObjectProtocol] = [ "userID" : userID as NSString, "endpointURL" : endpointURL as NSString ] 22 | 23 | // Set broadcast settings 24 | let broadcastConfiguration = RPBroadcastConfiguration() 25 | broadcastConfiguration.clipDuration = 5 26 | 27 | // Tell ReplayKit that the extension is finished setting up and can begin broadcasting 28 | self.extensionContext?.completeRequest(withBroadcast: broadcastURL!, broadcastConfiguration: broadcastConfiguration, setupInfo: setupInfo) 29 | } 30 | 31 | func userDidCancelSetup() { 32 | let error = NSError(domain: "YouAppDomain", code: -1, userInfo: nil) 33 | // Tell ReplayKit that the extension was cancelled by the user 34 | self.extensionContext?.cancelRequest(withError: error) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MyBroadcastUploadUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyBroadcastUploadUI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | NSExtensionActivationRule 28 | 29 | NSExtensionActivationSupportsReplayKitStreaming 30 | 31 | 32 | 33 | NSExtensionMainStoryboard 34 | MainInterface 35 | NSExtensionPointIdentifier 36 | com.apple.broadcast-services 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /MyCallDirectory/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyCallDirectory 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.callkit.call-directory 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).CallDirectoryHandler 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyClassKitContextProvider/ContextRequestHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContextRequestHandler.swift 3 | // MyClassKitContextProvider 4 | // 5 | // Created by Jeff Kelley on 5/9/19. 6 | // Copyright © 2019 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import ClassKit 10 | 11 | class ContextRequestHandler: NSObject, NSExtensionRequestHandling, CLSContextProvider { 12 | 13 | func beginRequest(with context: NSExtensionContext) { 14 | // This is a required function defined by the NSExtensionRequestHandling protocol. This function 15 | // will be called once per connection from a host. Therefore, it may be called several times, if 16 | // the host disconnects and reconnects several times. This is where you can have code that performs 17 | // one-time initialization. 18 | } 19 | 20 | func updateDescendants(of context: CLSContext, completion: @escaping (Error?) -> Void) { 21 | let error: Error? = nil 22 | 23 | // This is where your code creates child contexts for the context passed in. 24 | // If there is nothing to do, call the completion (below) and you're done. 25 | // 26 | // Otherwise, create children, add them to context and then -[CLSDataStore saveWithCompletion:]. 27 | // 28 | // If your extension is being called, an instructor is probably creating a Handout and actively 29 | // browsing for quizzes/activities. Your extension should try to update your context tree quickly. 30 | // Note: your call to -[CLSDataStore saveWithCompletion:] will likelty trigger a refresh of the 31 | // available quizzes/activities, so call it as soon as you can. 32 | 33 | // Call completion when you are finished. 34 | completion(error) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MyClassKitContextProvider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyClassKitContextProvider 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.classkit.context-provider 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).ContextRequestHandler 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyClassKitContextProvider/MyClassKitContextProvider.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.ClassKit-environment 6 | development 7 | 8 | 9 | -------------------------------------------------------------------------------- /MyContentBlocker/ContentBlockerRequestHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentBlockerRequestHandler.swift 3 | // MyContentBlocker 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MobileCoreServices 11 | 12 | class ContentBlockerRequestHandler: NSObject, NSExtensionRequestHandling { 13 | 14 | func beginRequest(with context: NSExtensionContext) { 15 | let attachment = NSItemProvider(contentsOf: Bundle.main.url(forResource: "blockerList", withExtension: "json"))! 16 | 17 | let item = NSExtensionItem() 18 | item.attachments = [attachment] 19 | 20 | context.completeRequest(returningItems: [item], completionHandler: nil) 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /MyContentBlocker/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyContentBlocker 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.Safari.content-blocker 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).ContentBlockerRequestHandler 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyContentBlocker/blockerList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "action": { 4 | "type": "block" 5 | }, 6 | "trigger": { 7 | "url-filter": "webkit.svg" 8 | } 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /MyCustomKeyboard/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyCustomKeyboard 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | IsASCIICapable 28 | 29 | PrefersRightToLeft 30 | 31 | PrimaryLanguage 32 | en-US 33 | RequestsOpenAccess 34 | 35 | 36 | NSExtensionPointIdentifier 37 | com.apple.keyboard-service 38 | NSExtensionPrincipalClass 39 | $(PRODUCT_MODULE_NAME).KeyboardViewController 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /MyDocumentProvider/DocumentPickerViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentPickerViewController.swift 3 | // MyDocumentProvider 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DocumentPickerViewController: UIDocumentPickerExtensionViewController { 12 | 13 | @IBAction func openDocument(_ sender: AnyObject?) { 14 | let documentURL = self.documentStorageURL!.appendingPathComponent("Untitled.txt") 15 | 16 | // TODO: if you do not have a corresponding file provider, you must ensure that the URL returned here is backed by a file 17 | self.dismissGrantingAccess(to: documentURL) 18 | } 19 | 20 | override func prepareForPresentation(in mode: UIDocumentPickerMode) { 21 | // TODO: present a view controller appropriate for picker mode here 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /MyDocumentProvider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyDocumentProvider 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | UIDocumentPickerModes 28 | 29 | UIDocumentPickerModeImport 30 | UIDocumentPickerModeOpen 31 | UIDocumentPickerModeExportToService 32 | UIDocumentPickerModeMoveToService 33 | 34 | UIDocumentPickerSupportedFileTypes 35 | 36 | public.content 37 | 38 | 39 | NSExtensionMainStoryboard 40 | MainInterface 41 | NSExtensionPointIdentifier 42 | com.apple.fileprovider-ui 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /MyDocumentProvider/MyDocumentProvider.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.slaunchaman.Turducken 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyFileProvider/FileProviderItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FileProviderItem.swift 3 | // MyFileProvider 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import FileProvider 10 | 11 | class FileProviderItem: NSObject, NSFileProviderItem { 12 | 13 | // TODO: implement an initializer to create an item from your extension's backing model 14 | // TODO: implement the accessors to return the values from your extension's backing model 15 | 16 | var itemIdentifier: NSFileProviderItemIdentifier { 17 | return NSFileProviderItemIdentifier("") 18 | } 19 | 20 | var parentItemIdentifier: NSFileProviderItemIdentifier { 21 | return NSFileProviderItemIdentifier("") 22 | } 23 | 24 | var capabilities: NSFileProviderItemCapabilities { 25 | return .allowsAll 26 | } 27 | 28 | var filename: String { 29 | return "" 30 | } 31 | 32 | var typeIdentifier: String { 33 | return "" 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /MyFileProvider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyFileProvider 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionFileProviderDocumentGroup 26 | group.com.slaunchaman.Turducken 27 | NSExtensionFileProviderSupportsEnumeration 28 | 29 | NSExtensionPointIdentifier 30 | com.apple.fileprovider-nonui 31 | NSExtensionPrincipalClass 32 | $(PRODUCT_MODULE_NAME).FileProviderExtension 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /MyFileProvider/MyFileProvider.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.slaunchaman.Turducken 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyFileProviderUI/DocumentActionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentActionViewController.swift 3 | // MyFileProviderUI 4 | // 5 | // Created by Jeff Kelley on 12/15/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FileProviderUI 11 | 12 | class DocumentActionViewController: FPUIActionExtensionViewController { 13 | 14 | @IBOutlet weak var identifierLabel: UILabel! 15 | @IBOutlet weak var actionTypeLabel: UILabel! 16 | 17 | override func prepare(forAction actionIdentifier: String, itemIdentifiers: [NSFileProviderItemIdentifier]) { 18 | identifierLabel?.text = actionIdentifier 19 | actionTypeLabel?.text = "Custom action" 20 | } 21 | 22 | override func prepare(forError error: Error) { 23 | identifierLabel?.text = error.localizedDescription 24 | actionTypeLabel?.text = "Authenticate" 25 | } 26 | 27 | @IBAction func doneButtonTapped(_ sender: Any) { 28 | // Perform the action and call the completion block. If an unrecoverable error occurs you must still call the completion block with an error. Use the error code FPUIExtensionErrorCode.failed to signal the failure. 29 | extensionContext.completeRequest() 30 | } 31 | 32 | @IBAction func cancelButtonTapped(_ sender: Any) { 33 | extensionContext.cancelRequest(withError: NSError(domain: FPUIErrorDomain, code: Int(FPUIExtensionErrorCode.userCancelled.rawValue), userInfo: nil)) 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /MyFileProviderUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyFileProviderUI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionFileProviderActions 26 | 27 | 28 | NSExtensionFileProviderActionActivationRule 29 | TRUEPREDICATE 30 | NSExtensionFileProviderActionIdentifier 31 | com.mycompany.FileProviderUI.CustomAction 32 | NSExtensionFileProviderActionName 33 | Custom Action 34 | 35 | 36 | NSExtensionMainStoryboard 37 | MainInterface 38 | NSExtensionPointIdentifier 39 | com.apple.fileprovider-actionsui 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /MyFinderSync/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyFinderSync 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | LSUIElement 26 | 27 | NSExtension 28 | 29 | NSExtensionAttributes 30 | 31 | NSExtensionPointIdentifier 32 | com.apple.FinderSync 33 | NSExtensionPrincipalClass 34 | $(PRODUCT_MODULE_NAME).FinderSync 35 | 36 | NSHumanReadableCopyright 37 | Copyright © 2017 Jeff Kelley. All rights reserved. 38 | NSPrincipalClass 39 | NSApplication 40 | 41 | 42 | -------------------------------------------------------------------------------- /MyFinderSync/MyFinderSync.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyFramework/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // Turducken 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /MyFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MyFramework/MyFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyFramework.h 3 | // MyFramework 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MyFramework. 12 | FOUNDATION_EXPORT double MyFrameworkVersionNumber; 13 | 14 | //! Project version string for MyFramework. 15 | FOUNDATION_EXPORT const unsigned char MyFrameworkVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /MyFrameworkTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MyFrameworkTests/MyFrameworkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MyFrameworkTests.swift 3 | // MyFrameworkTests 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import MyFramework 11 | 12 | class MyFrameworkTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | XCTAssertTrue(true) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /MyIntents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyIntents 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | IntentsRestrictedWhileLocked 28 | 29 | IntentsSupported 30 | 31 | INSendMessageIntent 32 | INSearchForMessagesIntent 33 | INSetMessageAttributeIntent 34 | 35 | 36 | NSExtensionPointIdentifier 37 | com.apple.intents-service 38 | NSExtensionPrincipalClass 39 | $(PRODUCT_MODULE_NAME).IntentHandler 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /MyIntentsUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyIntentsUI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | IntentsSupported 28 | 29 | INSendMessageIntent 30 | 31 | 32 | NSExtensionMainStoryboard 33 | MainInterface 34 | NSExtensionPointIdentifier 35 | com.apple.intents-ui-service 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /MyIntentsUI/IntentViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IntentViewController.swift 3 | // MyIntentsUI 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import IntentsUI 10 | 11 | // As an example, this extension's Info.plist has been configured to handle interactions for INSendMessageIntent. 12 | // You will want to replace this or add other intents as appropriate. 13 | // The intents whose interactions you wish to handle must be declared in the extension's Info.plist. 14 | 15 | // You can test this example integration by saying things to Siri like: 16 | // "Send a message using " 17 | 18 | class IntentViewController: UIViewController, INUIHostedViewControlling { 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | // Do any additional setup after loading the view. 23 | } 24 | 25 | override func didReceiveMemoryWarning() { 26 | super.didReceiveMemoryWarning() 27 | // Dispose of any resources that can be recreated. 28 | } 29 | 30 | // MARK: - INUIHostedViewControlling 31 | 32 | // Prepare your view controller for the interaction to handle. 33 | func configure(with interaction: INInteraction, context: INUIHostedViewContext, completion: @escaping ((CGSize) -> Void)) { 34 | // Do configuration here, including preparing views and calculating a desired size for presentation. 35 | 36 | completion(self.desiredSize) 37 | } 38 | 39 | var desiredSize: CGSize { 40 | return self.extensionContext!.hostedViewMaximumAllowedSize 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /MyMacAudioUnit/AudioUnitViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioUnitViewController.swift 3 | // MyMacAudioUnit 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import CoreAudioKit 10 | 11 | public class AudioUnitViewController: AUViewController, AUAudioUnitFactory { 12 | var audioUnit: AUAudioUnit? 13 | 14 | public override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | if audioUnit == nil { 18 | return 19 | } 20 | 21 | // Get the parameter tree and add observers for any parameters that the UI needs to keep in sync with the AudioUnit 22 | } 23 | 24 | public func createAudioUnit(with componentDescription: AudioComponentDescription) throws -> AUAudioUnit { 25 | audioUnit = try MyMacAudioUnitAudioUnit(componentDescription: componentDescription, options: []) 26 | 27 | return audioUnit! 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /MyMacAudioUnit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyMacAudioUnit 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | AudioComponents 30 | 31 | 32 | description 33 | MyMacAudioUnit 34 | factoryFunction 35 | $(PRODUCT_MODULE_NAME).AudioUnitViewController 36 | manufacturer 37 | JKJK 38 | name 39 | JKJK: MyMacAudioUnit 40 | sandboxSafe 41 | 42 | subtype 43 | clst 44 | tags 45 | 46 | Synthesizer 47 | 48 | type 49 | aumu 50 | version 51 | 67072 52 | 53 | 54 | 55 | NSExtensionPointIdentifier 56 | com.apple.AudioUnit-UI 57 | NSExtensionPrincipalClass 58 | $(PRODUCT_MODULE_NAME).AudioUnitViewController 59 | 60 | NSHumanReadableCopyright 61 | Copyright © 2017 Jeff Kelley. All rights reserved. 62 | 63 | 64 | -------------------------------------------------------------------------------- /MyMacAudioUnit/MyMacAudioUnit-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyMacAudioUnit-Bridging-Header.h 3 | // MyMacAudioUnit 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #import "MyMacAudioUnitAudioUnit.h" 10 | -------------------------------------------------------------------------------- /MyMacAudioUnit/MyMacAudioUnit.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacAudioUnit/MyMacAudioUnitAudioUnit.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyMacAudioUnitAudioUnit.h 3 | // MyMacAudioUnit 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // Define parameter addresses. 12 | extern const AudioUnitParameterID myParam1; 13 | 14 | @interface MyMacAudioUnitAudioUnit : AUAudioUnit 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MyMacContentBlocker/ContentBlockerRequestHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentBlockerRequestHandler.swift 3 | // MyMacContentBlocker 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class ContentBlockerRequestHandler: NSObject, NSExtensionRequestHandling { 12 | 13 | func beginRequest(with context: NSExtensionContext) { 14 | let attachment = NSItemProvider(contentsOf: Bundle.main.url(forResource: "blockerList", withExtension: "json"))! 15 | 16 | let item = NSExtensionItem() 17 | item.attachments = [attachment] 18 | 19 | context.completeRequest(returningItems: [item], completionHandler: nil) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /MyMacContentBlocker/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyMacContentBlocker 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionPointIdentifier 28 | com.apple.Safari.content-blocker 29 | NSExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).ContentBlockerRequestHandler 31 | 32 | NSHumanReadableCopyright 33 | Copyright © 2017 Jeff Kelley. All rights reserved. 34 | NSHumanReadableDescription 35 | Add a description of what your extension does here. 36 | 37 | 38 | -------------------------------------------------------------------------------- /MyMacContentBlocker/MyMacContentBlocker.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacContentBlocker/blockerList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "action": { 4 | "type": "block" 5 | }, 6 | "trigger": { 7 | "url-filter": "webkit.svg" 8 | } 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /MyMacNetworkAppProxy/AppProxyProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppProxyProvider.swift 3 | // MyMacNetworkAppProxy 4 | // 5 | // Created by Jeff Kelley on 12/15/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import NetworkExtension 10 | 11 | class AppProxyProvider: NEAppProxyProvider { 12 | 13 | override func startProxy(options: [String : Any]?, completionHandler: @escaping (Error?) -> Void) { 14 | // Add code here to start the process of connecting the tunnel. 15 | } 16 | 17 | override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 18 | // Add code here to start the process of stopping the tunnel. 19 | completionHandler() 20 | } 21 | 22 | override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { 23 | // Add code here to handle the message. 24 | if let handler = completionHandler { 25 | handler(messageData) 26 | } 27 | } 28 | 29 | override func sleep(completionHandler: @escaping () -> Void) { 30 | // Add code here to get ready to sleep. 31 | completionHandler() 32 | } 33 | 34 | override func wake() { 35 | // Add code here to wake up. 36 | } 37 | 38 | override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { 39 | // Add code here to handle the incoming flow. 40 | return false 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MyMacNetworkAppProxy/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyMacNetworkAppProxy 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionPointIdentifier 28 | com.apple.networkextension.app-proxy 29 | NSExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).AppProxyProvider 31 | 32 | NSHumanReadableCopyright 33 | Copyright © 2017 Jeff Kelley. All rights reserved. 34 | 35 | 36 | -------------------------------------------------------------------------------- /MyMacNetworkAppProxy/MyMacNetworkAppProxy.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.developer.networking.networkextension 8 | 9 | packet-tunnel-provider 10 | app-proxy-provider 11 | content-filter-provider 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MyMacNetworkPacketTunnel/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyMacNetworkPacketTunnel 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionPointIdentifier 28 | com.apple.networkextension.packet-tunnel 29 | NSExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).PacketTunnelProvider 31 | 32 | NSHumanReadableCopyright 33 | Copyright © 2017 Jeff Kelley. All rights reserved. 34 | 35 | 36 | -------------------------------------------------------------------------------- /MyMacNetworkPacketTunnel/MyMacNetworkPacketTunnel.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.developer.networking.networkextension 8 | 9 | packet-tunnel-provider 10 | app-proxy-provider 11 | content-filter-provider 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MyMacNetworkPacketTunnel/PacketTunnelProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PacketTunnelProvider.swift 3 | // MyMacNetworkPacketTunnel 4 | // 5 | // Created by Jeff Kelley on 12/15/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import NetworkExtension 10 | 11 | class PacketTunnelProvider: NEPacketTunnelProvider { 12 | 13 | override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) { 14 | // Add code here to start the process of connecting the tunnel. 15 | } 16 | 17 | override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 18 | // Add code here to start the process of stopping the tunnel. 19 | completionHandler() 20 | } 21 | 22 | override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { 23 | // Add code here to handle the message. 24 | if let handler = completionHandler { 25 | handler(messageData) 26 | } 27 | } 28 | 29 | override func sleep(completionHandler: @escaping () -> Void) { 30 | // Add code here to get ready to sleep. 31 | completionHandler() 32 | } 33 | 34 | override func wake() { 35 | // Add code here to wake up. 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MyMacNotificationService/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyMacNotificationService 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionPointIdentifier 28 | com.apple.usernotifications.service 29 | NSExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).NotificationService 31 | 32 | NSHumanReadableCopyright 33 | Copyright © 2019 Jeff Kelley. All rights reserved. 34 | 35 | 36 | -------------------------------------------------------------------------------- /MyMacNotificationService/NotificationService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationService.swift 3 | // MyMacNotificationService 4 | // 5 | // Created by Jeff Kelley on 5/9/19. 6 | // Copyright © 2019 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UserNotifications 10 | 11 | class NotificationService: UNNotificationServiceExtension { 12 | 13 | var contentHandler: ((UNNotificationContent) -> Void)? 14 | var bestAttemptContent: UNMutableNotificationContent? 15 | 16 | override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { 17 | self.contentHandler = contentHandler 18 | bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) 19 | 20 | if let bestAttemptContent = bestAttemptContent { 21 | // Modify the notification content here... 22 | bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" 23 | 24 | contentHandler(bestAttemptContent) 25 | } 26 | } 27 | 28 | override func serviceExtensionTimeWillExpire() { 29 | // Called just before the extension will be terminated by the system. 30 | // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. 31 | if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { 32 | contentHandler(bestAttemptContent) 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /MyMacPhotoEditing/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyMacPhotoEditing 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | PHSupportedMediaTypes 30 | 31 | Image 32 | 33 | 34 | NSExtensionPointIdentifier 35 | com.apple.photo-editing 36 | NSExtensionPrincipalClass 37 | $(PRODUCT_MODULE_NAME).PhotoEditingViewController 38 | 39 | NSHumanReadableCopyright 40 | Copyright © 2017 Jeff Kelley. All rights reserved. 41 | 42 | 43 | -------------------------------------------------------------------------------- /MyMacPhotoEditing/MyMacPhotoEditing.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacPhotoProject/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyMacPhotoProject 9 | CFBundleDocumentTypes 10 | 11 | 12 | CFBundleTypeRole 13 | Editor 14 | LSItemContentTypes 15 | 16 | com.slaunchaman.TurduckenMac.MyMacPhotoProject-document-type 17 | 18 | 19 | 20 | CFBundleExecutable 21 | $(EXECUTABLE_NAME) 22 | CFBundleIdentifier 23 | $(PRODUCT_BUNDLE_IDENTIFIER) 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | $(PRODUCT_NAME) 28 | CFBundlePackageType 29 | XPC! 30 | CFBundleShortVersionString 31 | 1.0 32 | CFBundleVersion 33 | 1 34 | LSMinimumSystemVersion 35 | $(MACOSX_DEPLOYMENT_TARGET) 36 | NSExtension 37 | 38 | NSExtensionAttributes 39 | 40 | PHProjectExtensionDefinesProjectTypes 41 | 42 | 43 | NSExtensionPointIdentifier 44 | com.apple.photo-project 45 | NSExtensionPrincipalClass 46 | $(PRODUCT_MODULE_NAME).PhotoProjectViewController 47 | 48 | NSHumanReadableCopyright 49 | Copyright © 2017 Jeff Kelley. All rights reserved. 50 | 51 | 52 | -------------------------------------------------------------------------------- /MyMacPhotoProject/MyMacPhotoProject.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacPhotoProject/PhotoProjectViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoProjectViewController.swift 3 | // MyMacPhotoProject 4 | // 5 | // Created by Jeff Kelley on 12/15/17. 6 | //Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import PhotosUI 11 | 12 | @available(OSXApplicationExtension 10.13, *) 13 | class PhotoProjectViewController: NSViewController, PHProjectExtensionController { 14 | 15 | var projectExtensionContext: PHProjectExtensionContext? { 16 | get { 17 | return extensionContext as? PHProjectExtensionContext 18 | } 19 | } 20 | 21 | override func viewDidLoad() { 22 | super.viewDidLoad() 23 | // Do view setup here. 24 | } 25 | 26 | // MARK: - PHProjectExtensionController 27 | 28 | var supportedProjectTypes: [PHProjectTypeDescription] { 29 | let projectTypes = [PHProjectTypeDescription]() 30 | // Fill the array with PHProjectTypeDescription instances representing you project types. 31 | // If you don't want to support custom project types set PHProjectExtensionDefinesProjectTypes to NO in the extension's Info.plist NSExtensionAttributes dictionary. 32 | return projectTypes 33 | } 34 | 35 | func beginProject(with extensionContext: PHProjectExtensionContext, projectInfo: PHProjectInfo, completion: @escaping (Error?) -> Void) { 36 | DispatchQueue.main.async { 37 | // do initialization here 38 | completion(nil) 39 | } 40 | } 41 | 42 | func resumeProject(with extensionContext: PHProjectExtensionContext, completion: @escaping (Error?) -> Void) { 43 | DispatchQueue.main.async { 44 | // do initialization here 45 | completion(nil) 46 | } 47 | } 48 | 49 | func finishProject(completionHandler completion: @escaping () -> Void) { 50 | // do any finalization here 51 | completion() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MyMacQuickLookPreview/Base.lproj/PreviewViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /MyMacQuickLookPreview/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyMacQuickLookPreview 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | QLSupportsSearchableItems 30 | 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.quicklook.preview 34 | NSExtensionPrincipalClass 35 | $(PRODUCT_MODULE_NAME).PreviewViewController 36 | 37 | NSHumanReadableCopyright 38 | Copyright © 2017 Jeff Kelley. All rights reserved. 39 | 40 | 41 | -------------------------------------------------------------------------------- /MyMacQuickLookPreview/MyMacQuickLookPreview.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacQuickLookPreview/PreviewViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewViewController.swift 3 | // MyMacQuickLookPreview 4 | // 5 | // Created by Jeff Kelley on 12/15/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Quartz 11 | 12 | class PreviewViewController: NSViewController, QLPreviewingController { 13 | 14 | override var nibName: NSNib.Name? { 15 | return "PreviewViewController" 16 | } 17 | 18 | override func loadView() { 19 | super.loadView() 20 | // Do any additional setup after loading the view from its nib. 21 | } 22 | 23 | func preparePreviewOfSearchableItem(identifier: String, queryString: String?, completionHandler handler: @escaping QLPreviewItemLoadingBlock) { 24 | // Perform any setup necessary in order to prepare the view. 25 | 26 | // Call the completion handler so Quick Look knows that the preview is fully loaded. 27 | // Quick Look will display a loading spinner while the completion handler is not called. 28 | handler(nil) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /MyMacShare/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyMacShare 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIconFile 12 | icon 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | XPC! 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSExtension 28 | 29 | NSExtensionAttributes 30 | 31 | NSExtensionActivationRule 32 | NSExtensionActivationSupportsText 33 | 34 | NSExtensionPointIdentifier 35 | com.apple.share-services 36 | NSExtensionPrincipalClass 37 | $(PRODUCT_MODULE_NAME).ShareViewController 38 | 39 | NSHumanReadableCopyright 40 | Copyright © 2017 Jeff Kelley. All rights reserved. 41 | 42 | 43 | -------------------------------------------------------------------------------- /MyMacShare/MyMacShare.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacShare/ShareViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShareViewController.swift 3 | // MyMacShare 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ShareViewController: NSViewController { 12 | 13 | override var nibName: NSNib.Name? { 14 | return "ShareViewController" 15 | } 16 | 17 | override func loadView() { 18 | super.loadView() 19 | 20 | // Insert code here to customize the view 21 | let item = self.extensionContext!.inputItems[0] as! NSExtensionItem 22 | if let attachments = item.attachments { 23 | NSLog("Attachments = %@", attachments as NSArray) 24 | } else { 25 | NSLog("No Attachments") 26 | } 27 | } 28 | 29 | @IBAction func send(_ sender: AnyObject?) { 30 | let outputItem = NSExtensionItem() 31 | // Complete implementation by setting the appropriate value on the output item 32 | 33 | let outputItems = [outputItem] 34 | self.extensionContext!.completeRequest(returningItems: outputItems, completionHandler: nil) 35 | } 36 | 37 | @IBAction func cancel(_ sender: AnyObject?) { 38 | let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) 39 | self.extensionContext!.cancelRequest(withError: cancelError) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /MyMacShare/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlaunchaMan/Turducken/8e321d4e36199165c9b49b323a1b0bb5e23ee7e0/MyMacShare/icon.icns -------------------------------------------------------------------------------- /MyMacSharedLinks/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyMacSharedLinks 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionPointIdentifier 28 | com.apple.Safari.sharedlinks-service 29 | NSExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).RequestHandler 31 | 32 | NSHumanReadableCopyright 33 | Copyright © 2017 Jeff Kelley. All rights reserved. 34 | 35 | 36 | -------------------------------------------------------------------------------- /MyMacSharedLinks/MyMacSharedLinks.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacSharedLinks/RequestHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RequestHandler.swift 3 | // MyMacSharedLinks 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class RequestHandler: NSObject, NSExtensionRequestHandling { 12 | 13 | func beginRequest(with context: NSExtensionContext) { 14 | let extensionItem = NSExtensionItem() 15 | 16 | // The keys of the user info dictionary match what data Safari is expecting for each Shared Links item. 17 | // For the date, use the publish date of the content being linked 18 | extensionItem.userInfo = [ AnyHashable("uniqueIdentifier"): "uniqueIdentifierForSampleItem", AnyHashable("urlString"): "http://apple.com", AnyHashable("date"): NSDate() ] 19 | 20 | extensionItem.attributedTitle = NSAttributedString(string: "Sample title") 21 | extensionItem.attributedContentText = NSAttributedString(string: "Sample description text") 22 | 23 | // You can supply a custom image to be used with your link as well. Use the NSExtensionItem's attachments property. 24 | // extensionItem.attachments = [ NSItemProvider(contentsOfURL: NSBundle.mainBundle().URLForResource("customLinkImage", withExtension: "png"))! ] 25 | 26 | context.completeRequest(returningItems: [extensionItem], completionHandler: nil) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /MyMacSpotlightIndex/IndexRequestHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndexRequestHandler.swift 3 | // MyMacSpotlightIndex 4 | // 5 | // Created by Jeff Kelley on 12/15/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import CoreSpotlight 10 | 11 | class IndexRequestHandler: CSIndexExtensionRequestHandler { 12 | 13 | override func searchableIndex(_ searchableIndex: CSSearchableIndex, reindexAllSearchableItemsWithAcknowledgementHandler acknowledgementHandler: @escaping () -> Void) { 14 | // Reindex all data with the provided index 15 | 16 | acknowledgementHandler() 17 | } 18 | 19 | override func searchableIndex(_ searchableIndex: CSSearchableIndex, reindexSearchableItemsWithIdentifiers identifiers: [String], acknowledgementHandler: @escaping () -> Void) { 20 | // Reindex any items with the given identifiers and the provided index 21 | 22 | acknowledgementHandler() 23 | } 24 | 25 | override func data(for searchableIndex: CSSearchableIndex, itemIdentifier: String, typeIdentifier: String) throws -> Data { 26 | // Replace with Data representation of requested type from item identifier 27 | 28 | return Data() 29 | } 30 | 31 | override func fileURL(for searchableIndex: CSSearchableIndex, itemIdentifier: String, typeIdentifier: String, inPlace: Bool) throws -> URL { 32 | // Replace with to return file url based on requested type from item identifier 33 | 34 | return URL(string:"file://")! 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /MyMacSpotlightIndex/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyMacSpotlightIndex 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionPointIdentifier 28 | com.apple.spotlight.index 29 | NSExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).IndexRequestHandler 31 | 32 | NSHumanReadableCopyright 33 | Copyright © 2017 Jeff Kelley. All rights reserved. 34 | 35 | 36 | -------------------------------------------------------------------------------- /MyMacSpotlightIndex/MyMacSpotlightIndex.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacToday/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyMacToday 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | NSExtensionPointVersion 30 | 2.0 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.widget-extension 34 | NSExtensionPrincipalClass 35 | $(PRODUCT_MODULE_NAME).TodayViewController 36 | com.apple.notificationcenter.widget.description 37 | MyMacToday 38 | 39 | NSHumanReadableCopyright 40 | Copyright © 2017 Jeff Kelley. All rights reserved. 41 | 42 | 43 | -------------------------------------------------------------------------------- /MyMacToday/MyMacToday.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMacToday/TodayViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodayViewController.swift 3 | // MyMacToday 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import NotificationCenter 11 | 12 | class TodayViewController: NSViewController, NCWidgetProviding { 13 | 14 | override var nibName: NSNib.Name? { 15 | return "TodayViewController" 16 | } 17 | 18 | func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { 19 | // Update your data and prepare for a snapshot. Call completion handler when you are done 20 | // with NoData if nothing has changed or NewData if there is new data since the last 21 | // time we called you 22 | completionHandler(.noData) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MyMacToday/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Display name and description for this extension. */ 2 | "CFBundleDisplayName" = "MyMacToday"; 3 | "com.apple.notificationcenter.widget.description" = "Sample description"; 4 | 5 | -------------------------------------------------------------------------------- /MyMaction/ActionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ActionViewController.swift 3 | // MyMaction 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ActionViewController: NSViewController { 12 | 13 | @IBOutlet var myTextView: NSTextView! 14 | 15 | override var nibName: NSNib.Name? { 16 | return "ActionViewController" 17 | } 18 | 19 | override func loadView() { 20 | super.loadView() 21 | 22 | // Insert code here to customize the view 23 | NSLog("Input Items = %@", self.extensionContext!.inputItems as NSArray) 24 | 25 | let sharedItem = self.extensionContext!.inputItems[0] as! NSExtensionItem 26 | let text = sharedItem.attributedContentText?.string 27 | 28 | if text != nil && !text!.isEmpty { 29 | self.myTextView.string = text! 30 | } 31 | } 32 | 33 | @IBAction func send(_ sender: AnyObject?) { 34 | // Note: The extension information in theInfo.plist is set to accept any type of content, but this example code only handles text. You should declare the specific types to be supported by your extension in the extension's Info.plist and then make sure to handle all your supported types. 35 | let outputItem = NSExtensionItem() 36 | outputItem.attributedContentText = self.myTextView.attributedString() 37 | 38 | let outputItems = [outputItem] 39 | self.extensionContext!.completeRequest(returningItems: outputItems, completionHandler: nil) 40 | } 41 | 42 | @IBAction func cancel(_ sender: AnyObject?) { 43 | let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) 44 | self.extensionContext!.cancelRequest(withError: cancelError) 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /MyMaction/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyMaction 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIconFile 12 | icon 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | XPC! 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSExtension 28 | 29 | NSExtensionAttributes 30 | 31 | NSExtensionActivationRule 32 | NSExtensionActivationSupportsText 33 | NSExtensionServiceRoleType 34 | NSExtensionServiceRoleTypeEditor 35 | 36 | NSExtensionPointIdentifier 37 | com.apple.ui-services 38 | NSExtensionPrincipalClass 39 | $(PRODUCT_MODULE_NAME).ActionViewController 40 | 41 | NSHumanReadableCopyright 42 | Copyright © 2017 Jeff Kelley. All rights reserved. 43 | 44 | 45 | -------------------------------------------------------------------------------- /MyMaction/MyMaction.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyMaction/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlaunchaMan/Turducken/8e321d4e36199165c9b49b323a1b0bb5e23ee7e0/MyMaction/icon.icns -------------------------------------------------------------------------------- /MyMessageFilter/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyMessageFilter 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | ILMessageFilterExtensionNetworkURL 28 | https://www.example-sms-filter-application.com/api 29 | 30 | NSExtensionPointIdentifier 31 | com.apple.identitylookup.message-filter 32 | NSExtensionPrincipalClass 33 | $(PRODUCT_MODULE_NAME).MessageFilterExtension 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /MyMetalLibrary/MyMetalLibrary.metal: -------------------------------------------------------------------------------- 1 | // 2 | // MyMetalLibrary.metal 3 | // MyMetalLibrary 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | 12 | 13 | -------------------------------------------------------------------------------- /MyNetworkAppProxy/AppProxyProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppProxyProvider.swift 3 | // MyNetworkAppProxy 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import NetworkExtension 10 | 11 | class AppProxyProvider: NEAppProxyProvider { 12 | 13 | override func startProxy(options: [String : Any]? = nil, completionHandler: @escaping (Error?) -> Void) { 14 | // Add code here to start the process of connecting the tunnel. 15 | } 16 | 17 | override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 18 | // Add code here to start the process of stopping the tunnel. 19 | completionHandler() 20 | } 21 | 22 | override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { 23 | // Add code here to handle the message. 24 | if let handler = completionHandler { 25 | handler(messageData) 26 | } 27 | } 28 | 29 | override func sleep(completionHandler: @escaping() -> Void) { 30 | // Add code here to get ready to sleep. 31 | completionHandler() 32 | } 33 | 34 | override func wake() { 35 | // Add code here to wake up. 36 | } 37 | 38 | override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { 39 | // Add code here to handle the incoming flow. 40 | return false 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MyNetworkAppProxy/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyNetworkAppProxy 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.networkextension.app-proxy 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).AppProxyProvider 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyNetworkAppProxy/MyNetworkAppProxy.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.slaunchaman.Turducken 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyNetworkDNSProxy/DNSProxyProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DNSProxyProvider.swift 3 | // MyNetworkDNSProxy 4 | // 5 | // Created by Jeff Kelley on 7/11/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import NetworkExtension 10 | 11 | class DNSProxyProvider: NEDNSProxyProvider { 12 | 13 | override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) { 14 | // Add code here to start the DNS proxy. 15 | completionHandler(nil) 16 | } 17 | 18 | override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 19 | // Add code here to stop the DNS proxy. 20 | completionHandler() 21 | } 22 | 23 | override func sleep(completionHandler: @escaping () -> Void) { 24 | // Add code here to get ready to sleep. 25 | completionHandler() 26 | } 27 | 28 | override func wake() { 29 | // Add code here to wake up. 30 | } 31 | 32 | override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { 33 | // Add code here to handle the incoming flow. 34 | return false 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /MyNetworkDNSProxy/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyNetworkDNSProxy 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.networkextension.dns-proxy 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).DNSProxyProvider 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyNetworkDNSProxy/MyNetworkDNSProxy.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.slaunchaman.Turducken 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyNetworkFilterControl/FilterControlProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FilterControlProvider.swift 3 | // MyNetworkFilterControl 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import NetworkExtension 10 | 11 | class FilterControlProvider: NEFilterControlProvider { 12 | 13 | override func startFilter(completionHandler: @escaping (Error?) -> Void) { 14 | // Add code to initialize the filter 15 | completionHandler(nil) 16 | } 17 | 18 | override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 19 | // Add code to clean up filter resources 20 | completionHandler() 21 | } 22 | 23 | override func handleNewFlow(_ flow: NEFilterFlow, completionHandler: @escaping (NEFilterControlVerdict) -> Void) { 24 | // Add code to determine if the flow should be dropped or not, downloading new rules if required 25 | completionHandler(.allow(withUpdateRules: false)) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MyNetworkFilterControl/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyNetworkFilterControl 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.networkextension.filter-control 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).FilterControlProvider 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyNetworkFilterControl/MyNetworkFilterControl.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.slaunchaman.Turducken 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyNetworkFilterData/FilterDataProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FilterDataProvider.swift 3 | // MyNetworkFilterData 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import NetworkExtension 10 | 11 | class FilterDataProvider: NEFilterDataProvider { 12 | 13 | override func startFilter(completionHandler: @escaping (Error?) -> Void) { 14 | // Add code to initialize the filter. 15 | completionHandler(nil) 16 | } 17 | 18 | override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 19 | // Add code to clean up filter resources. 20 | completionHandler() 21 | } 22 | 23 | override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict { 24 | // Add code to determine if the flow should be dropped or not, downloading new rules if required. 25 | return .allow() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MyNetworkFilterData/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyNetworkFilterData 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.networkextension.filter-data 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).FilterDataProvider 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyNetworkFilterData/MyNetworkFilterData.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.slaunchaman.Turducken 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyNetworkPacketTunnel/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyNetworkPacketTunnel 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.networkextension.packet-tunnel 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).PacketTunnelProvider 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyNetworkPacketTunnel/MyNetworkPacketTunnel.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.slaunchaman.Turducken 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MyNetworkPacketTunnel/PacketTunnelProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PacketTunnelProvider.swift 3 | // MyNetworkPacketTunnel 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import NetworkExtension 10 | 11 | class PacketTunnelProvider: NEPacketTunnelProvider { 12 | 13 | override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) { 14 | // Add code here to start the process of connecting the tunnel. 15 | } 16 | 17 | override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { 18 | // Add code here to start the process of stopping the tunnel. 19 | completionHandler() 20 | } 21 | 22 | override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { 23 | // Add code here to handle the message. 24 | if let handler = completionHandler { 25 | handler(messageData) 26 | } 27 | } 28 | 29 | override func sleep(completionHandler: @escaping () -> Void) { 30 | // Add code here to get ready to sleep. 31 | completionHandler() 32 | } 33 | 34 | override func wake() { 35 | // Add code here to wake up. 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MyNotificationContent/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyNotificationContent 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | UNNotificationExtensionCategory 28 | myNotificationCategory 29 | UNNotificationExtensionInitialContentSizeRatio 30 | 1 31 | 32 | NSExtensionMainStoryboard 33 | MainInterface 34 | NSExtensionPointIdentifier 35 | com.apple.usernotifications.content-extension 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /MyNotificationContent/NotificationViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationViewController.swift 3 | // MyNotificationContent 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import UserNotifications 11 | import UserNotificationsUI 12 | 13 | class NotificationViewController: UIViewController, UNNotificationContentExtension { 14 | 15 | @IBOutlet var label: UILabel? 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | // Do any required interface initialization here. 20 | } 21 | 22 | func didReceive(_ notification: UNNotification) { 23 | self.label?.text = notification.request.content.body 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /MyNotificationService/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyNotificationService 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.usernotifications.service 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).NotificationService 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyNotificationService/NotificationService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationService.swift 3 | // MyNotificationService 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UserNotifications 10 | 11 | class NotificationService: UNNotificationServiceExtension { 12 | 13 | var contentHandler: ((UNNotificationContent) -> Void)? 14 | var bestAttemptContent: UNMutableNotificationContent? 15 | 16 | override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { 17 | self.contentHandler = contentHandler 18 | bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) 19 | 20 | if let bestAttemptContent = bestAttemptContent { 21 | // Modify the notification content here... 22 | bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" 23 | 24 | contentHandler(bestAttemptContent) 25 | } 26 | } 27 | 28 | override func serviceExtensionTimeWillExpire() { 29 | // Called just before the extension will be terminated by the system. 30 | // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. 31 | if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { 32 | contentHandler(bestAttemptContent) 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /MyPhotoEditing/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyPhotoEditing 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | PHSupportedMediaTypes 28 | 29 | Image 30 | 31 | 32 | NSExtensionMainStoryboard 33 | MainInterface 34 | NSExtensionPointIdentifier 35 | com.apple.photo-editing 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /MyQuickLookPreview/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyQuickLookPreview 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | QLSupportedContentTypes 28 | 29 | QLSupportsSearchableItems 30 | 31 | 32 | NSExtensionMainStoryboard 33 | MainInterface 34 | NSExtensionPointIdentifier 35 | com.apple.quicklook.preview 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /MyQuickLookPreview/PreviewViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewViewController.swift 3 | // MyQuickLookPreview 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import QuickLook 11 | 12 | class PreviewViewController: UIViewController, QLPreviewingController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | // Do any additional setup after loading the view from its nib. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | func preparePreviewOfSearchableItem(identifier: String, queryString: String?, completionHandler handler: @escaping (Error?) -> Void) { 25 | // Perform any setup necessary in order to prepare the view. 26 | 27 | // Call the completion handler so Quick Look knows that the preview is fully loaded. 28 | // Quick Look will display a loading spinner while the completion handler is not called. 29 | handler(nil) 30 | } 31 | 32 | /* 33 | * Implement this method if you support previewing files. 34 | * Add the supported content types to the QLSupportedContentTypes array in the Info.plist of the extension. 35 | * 36 | func preparePreviewOfFile(at URL: URL, completionHandler handler: @escaping QLPreviewItemLoadingBlock) { 37 | 38 | handler(nil) 39 | } 40 | */ 41 | 42 | } 43 | -------------------------------------------------------------------------------- /MySafariExtension/MySafariExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MySafariExtension/SafariExtensionHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SafariExtensionHandler.swift 3 | // MySafariExtension 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import SafariServices 10 | 11 | class SafariExtensionHandler: SFSafariExtensionHandler { 12 | 13 | override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) { 14 | // This method will be called when a content script provided by your extension calls safari.extension.dispatchMessage("message"). 15 | page.getPropertiesWithCompletionHandler { properties in 16 | NSLog("The extension received a message (\(messageName)) from a script injected into (\(String(describing: properties?.url))) with userInfo (\(userInfo ?? [:]))") 17 | } 18 | } 19 | 20 | override func toolbarItemClicked(in window: SFSafariWindow) { 21 | // This method will be called when your toolbar item is clicked. 22 | NSLog("The extension's toolbar item was clicked") 23 | } 24 | 25 | override func validateToolbarItem(in window: SFSafariWindow, validationHandler: @escaping ((Bool, String) -> Void)) { 26 | // This is called when Safari's state changed in some way that would require the extension's toolbar item to be validated again. 27 | validationHandler(true, "") 28 | } 29 | 30 | override func popoverViewController() -> SFSafariExtensionViewController { 31 | return SafariExtensionViewController.shared 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /MySafariExtension/SafariExtensionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SafariExtensionViewController.swift 3 | // MySafariExtension 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import SafariServices 10 | 11 | class SafariExtensionViewController: SFSafariExtensionViewController { 12 | 13 | static let shared = SafariExtensionViewController() 14 | 15 | } 16 | -------------------------------------------------------------------------------- /MySafariExtension/ToolbarItemIcon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SlaunchaMan/Turducken/8e321d4e36199165c9b49b323a1b0bb5e23ee7e0/MySafariExtension/ToolbarItemIcon.pdf -------------------------------------------------------------------------------- /MySafariExtension/script.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function(event) { 2 | safari.extension.dispatchMessage("Hello World!"); 3 | }); 4 | -------------------------------------------------------------------------------- /MyShare/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /MyShare/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyShare 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | NSExtensionActivationRule 28 | NSExtensionActivationSupportsText 29 | 30 | NSExtensionMainStoryboard 31 | MainInterface 32 | NSExtensionPointIdentifier 33 | com.apple.share-services 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /MyShare/ShareViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShareViewController.swift 3 | // MyShare 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Social 11 | 12 | class ShareViewController: SLComposeServiceViewController { 13 | 14 | override func isContentValid() -> Bool { 15 | // Do validation of contentText and/or NSExtensionContext attachments here 16 | return true 17 | } 18 | 19 | override func didSelectPost() { 20 | // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments. 21 | 22 | // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context. 23 | self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) 24 | } 25 | 26 | override func configurationItems() -> [Any]! { 27 | // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here. 28 | return [] 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /MySmartCardToken/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MySmartCardToken 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | com.apple.ctk.aid 30 | uhhhhhhh 31 | com.apple.ctk.class-id 32 | com.slaunchaman.TurduckenMac.MySmartCardToken 33 | com.apple.ctk.driver-class 34 | $(PRODUCT_MODULE_NAME).TokenDriver 35 | com.apple.ctk.token-type 36 | smartcard 37 | 38 | NSExtensionPointIdentifier 39 | com.apple.ctk-tokens 40 | 41 | NSHumanReadableCopyright 42 | Copyright © 2017 Jeff Kelley. All rights reserved. 43 | 44 | 45 | -------------------------------------------------------------------------------- /MySmartCardToken/MySmartCardToken.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.smartcard 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MySmartCardToken/Token.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Token.swift 3 | // MySmartCardToken 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import CryptoTokenKit 10 | 11 | class Token: TKSmartCardToken, TKTokenDelegate { 12 | 13 | init(smartCard: TKSmartCard, aid AID: Data?, tokenDriver: TKSmartCardTokenDriver) throws { 14 | let instanceID = "token_instance_id" // Fill in a unique persistent identifier of the token instance. 15 | super.init(smartCard: smartCard, aid:AID, instanceID:instanceID, tokenDriver: tokenDriver) 16 | // Insert code here to enumerate token objects and populate keychainContents with instances of TKTokenKeychainCertificate, TKTokenKeychainKey, etc. 17 | let items = [TKTokenKeychainItem]() 18 | self.keychainContents!.fill(with: items) 19 | } 20 | 21 | func createSession(_ token: TKToken) throws -> TKTokenSession { 22 | return TokenSession(token:self) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MySmartCardToken/TokenDriver.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TokenDriver.swift 3 | // MySmartCardToken 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import CryptoTokenKit 10 | 11 | class TokenDriver: TKSmartCardTokenDriver, TKSmartCardTokenDriverDelegate { 12 | 13 | func tokenDriver(_ driver: TKSmartCardTokenDriver, createTokenFor smartCard: TKSmartCard, aid AID: Data?) throws -> TKSmartCardToken { 14 | return try Token(smartCard: smartCard, aid: AID, tokenDriver: self) 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /MySpotlightIndex/IndexRequestHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndexRequestHandler.swift 3 | // MySpotlightIndex 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import CoreSpotlight 10 | 11 | class IndexRequestHandler: CSIndexExtensionRequestHandler { 12 | 13 | override func searchableIndex(_ searchableIndex: CSSearchableIndex, reindexAllSearchableItemsWithAcknowledgementHandler acknowledgementHandler: @escaping () -> Void) { 14 | // Reindex all data with the provided index 15 | 16 | acknowledgementHandler() 17 | } 18 | 19 | override func searchableIndex(_ searchableIndex: CSSearchableIndex, reindexSearchableItemsWithIdentifiers identifiers: [String], acknowledgementHandler: @escaping () -> Void) { 20 | // Reindex any items with the given identifiers and the provided index 21 | 22 | acknowledgementHandler() 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MySpotlightIndex/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MySpotlightIndex 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.spotlight.index 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).IndexRequestHandler 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyStaticLibrary/MyStaticLibrary.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyStaticLibrary.h 3 | // MyStaticLibrary 4 | // 5 | // Created by Jeff Kelley on 7/11/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MyStaticLibrary : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MyStaticLibrary/MyStaticLibrary.m: -------------------------------------------------------------------------------- 1 | // 2 | // MyStaticLibrary.m 3 | // MyStaticLibrary 4 | // 5 | // Created by Jeff Kelley on 7/11/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | #import "MyStaticLibrary.h" 10 | 11 | @implementation MyStaticLibrary 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MyTVBroadcastUI/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /MyTVBroadcastUI/BroadcastViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BroadcastViewController.swift 3 | // MyTVBroadcastUI 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import ReplayKit 10 | 11 | class BroadcastViewController: UIViewController { 12 | 13 | // Called when the user has finished interacting with the view controller and a broadcast stream can start 14 | func userDidFinishSetup() { 15 | // Broadcast url that will be returned to the application 16 | let broadcastURL = URL(string:"http://broadcastURL_example/stream1") 17 | 18 | // Service specific broadcast data example which will be supplied to the process extension during broadcast 19 | let userID = "user1" 20 | let endpointURL = "http://broadcastURL_example/stream1/upload" 21 | let setupInfo: [String: NSCoding & NSObjectProtocol] = [ "userID" : userID as NSString, "endpointURL" : endpointURL as NSString ] 22 | 23 | // Set broadcast settings 24 | let broadcastConfiguration = RPBroadcastConfiguration() 25 | broadcastConfiguration.clipDuration = 5 26 | 27 | // Tell ReplayKit that the extension is finished setting up and can begin broadcasting 28 | self.extensionContext?.completeRequest(withBroadcast: broadcastURL!, broadcastConfiguration: broadcastConfiguration, setupInfo: setupInfo) 29 | } 30 | 31 | func userDidCancelSetup() { 32 | let error = NSError(domain: "YouAppDomain", code: -1, userInfo: nil) 33 | // Tell ReplayKit that the extension was cancelled by the user 34 | self.extensionContext?.cancelRequest(withError: error) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MyTVBroadcastUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyTVBroadcastUI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | NSExtensionActivationRule 28 | 29 | NSExtensionActivationSupportsReplayKitStreaming 30 | 31 | 32 | 33 | NSExtensionMainStoryboard 34 | MainInterface 35 | NSExtensionPointIdentifier 36 | com.apple.broadcast-services 37 | 38 | UIRequiredDeviceCapabilities 39 | 40 | arm64 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /MyTVBroadcastUpload/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyTVBroadcastUpload 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionPointIdentifier 26 | com.apple.broadcast-services 27 | NSExtensionPrincipalClass 28 | $(PRODUCT_MODULE_NAME).MovieClipHandler 29 | RPBroadcastProcessMode 30 | RPBroadcastProcessModeMP4Clip 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | arm64 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /MyTVBroadcastUpload/MovieClipHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MovieClipHandler.swift 3 | // MyTVBroadcastUpload 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import ReplayKit 11 | 12 | class MovieClipHandler: RPBroadcastMP4ClipHandler { 13 | 14 | override func processMP4Clip(with mp4ClipURL: URL?, setupInfo: [String : NSObject]?, finished: Bool) { 15 | // Get the endpoint url supplied by the UI extension in the service info dictionary 16 | let url = URL(string: setupInfo!["endpointURL"] as! String) 17 | 18 | // Set up the request 19 | var request = URLRequest(url: url!) 20 | request.httpMethod = "POST" 21 | 22 | // Upload the movie file with an upload task 23 | let session = URLSession.shared 24 | let uploadTask = session.uploadTask(with: request, fromFile: url!) { (data, response, error) in 25 | if (error != nil) { 26 | // Handle error locally 27 | } 28 | 29 | // Update broadcast settings if necessary 30 | let broadcastConfiguration = RPBroadcastConfiguration() 31 | broadcastConfiguration.clipDuration = 5 32 | 33 | // Tell ReplayKit that processing is complete for thie clip 34 | self.finishedProcessingMP4Clip(withUpdatedBroadcastConfiguration: broadcastConfiguration, error: nil) 35 | } 36 | 37 | uploadTask.resume() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MyTVBroadcastUpload/SampleHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SampleHandler.swift 3 | // MyTVBroadcastUpload 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import ReplayKit 10 | 11 | // To handle samples with a subclass of RPBroadcastSampleHandler set the following in the extension's Info.plist file: 12 | // - RPBroadcastProcessMode should be set to RPBroadcastProcessModeSampleBuffer 13 | // - NSExtensionPrincipalClass should be set to this class 14 | 15 | class SampleHandler: RPBroadcastSampleHandler { 16 | 17 | override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) { 18 | // User has requested to start the broadcast. Setup info from the UI extension will be supplied. 19 | } 20 | 21 | override func broadcastPaused() { 22 | // User has requested to pause the broadcast. Samples will stop being delivered. 23 | } 24 | 25 | override func broadcastResumed() { 26 | // User has requested to resume the broadcast. Samples delivery will resume. 27 | } 28 | 29 | override func broadcastFinished() { 30 | // User has requested to finish the broadcast. 31 | } 32 | 33 | override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { 34 | switch sampleBufferType { 35 | case RPSampleBufferType.video: 36 | // Handle audio sample buffer 37 | break 38 | case RPSampleBufferType.audioApp: 39 | // Handle audio sample buffer for app audio 40 | break 41 | case RPSampleBufferType.audioMic: 42 | // Handle audio sample buffer for mic audio 43 | break 44 | @unknown default: 45 | fatalError() 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MyTVBroadcastUploadUI/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /MyTVBroadcastUploadUI/BroadcastViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BroadcastViewController.swift 3 | // MyTVBroadcastUploadUI 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import ReplayKit 10 | 11 | class BroadcastViewController: UIViewController { 12 | 13 | // Called when the user has finished interacting with the view controller and a broadcast stream can start 14 | func userDidFinishSetup() { 15 | // Broadcast url that will be returned to the application 16 | let broadcastURL = URL(string:"http://broadcastURL_example/stream1") 17 | 18 | // Service specific broadcast data example which will be supplied to the process extension during broadcast 19 | let userID = "user1" 20 | let endpointURL = "http://broadcastURL_example/stream1/upload" 21 | let setupInfo: [String: NSCoding & NSObjectProtocol] = [ "userID" : userID as NSString, "endpointURL" : endpointURL as NSString ] 22 | 23 | // Set broadcast settings 24 | let broadcastConfiguration = RPBroadcastConfiguration() 25 | broadcastConfiguration.clipDuration = 5 26 | 27 | // Tell ReplayKit that the extension is finished setting up and can begin broadcasting 28 | self.extensionContext?.completeRequest(withBroadcast: broadcastURL!, broadcastConfiguration: broadcastConfiguration, setupInfo: setupInfo) 29 | } 30 | 31 | func userDidCancelSetup() { 32 | let error = NSError(domain: "YouAppDomain", code: -1, userInfo: nil) 33 | // Tell ReplayKit that the extension was cancelled by the user 34 | self.extensionContext?.cancelRequest(withError: error) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MyTVBroadcastUploadUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyTVBroadcastUploadUI 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | NSExtensionActivationRule 28 | 29 | NSExtensionActivationSupportsReplayKitStreaming 30 | 31 | 32 | 33 | NSExtensionMainStoryboard 34 | MainInterface 35 | NSExtensionPointIdentifier 36 | com.apple.broadcast-services 37 | 38 | UIRequiredDeviceCapabilities 39 | 40 | arm64 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /MyTVServices/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyTVServices 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | TVExtensionProtocols 28 | 29 | TVTopShelfProvider 30 | 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.tv-services 34 | NSExtensionPrincipalClass 35 | $(PRODUCT_MODULE_NAME).ServiceProvider 36 | 37 | UIRequiredDeviceCapabilities 38 | 39 | arm64 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /MyTVServices/ServiceProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceProvider.swift 3 | // MyTVServices 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import TVServices 11 | 12 | class ServiceProvider: NSObject, TVTopShelfProvider { 13 | 14 | override init() { 15 | super.init() 16 | } 17 | 18 | // MARK: - TVTopShelfProvider protocol 19 | 20 | var topShelfStyle: TVTopShelfContentStyle { 21 | // Return desired Top Shelf style. 22 | return .sectioned 23 | } 24 | 25 | var topShelfItems: [TVContentItem] { 26 | // Create an array of TVContentItems. 27 | return [] 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /MyThumbnail/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyThumbnail 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | QLSupportedContentTypes 28 | 29 | 30 | NSExtensionPointIdentifier 31 | com.apple.quicklook.thumbnail 32 | NSExtensionPrincipalClass 33 | $(PRODUCT_MODULE_NAME).ThumbnailProvider 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /MyThumbnail/ThumbnailProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThumbnailProvider.swift 3 | // MyThumbnail 4 | // 5 | // Created by Jeff Kelley on 6/17/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import QuickLook 11 | 12 | class ThumbnailProvider: QLThumbnailProvider { 13 | 14 | override func provideThumbnail(for request: QLFileThumbnailRequest, _ handler: @escaping (QLThumbnailReply?, Error?) -> Void) { 15 | 16 | // There are three ways to provide a thumbnail through a QLThumbnailReply. Only one of them should be used. 17 | 18 | // First way: Draw the thumbnail into the current context, set up with UIKit's coordinate system. 19 | handler(QLThumbnailReply(contextSize: request.maximumSize, currentContextDrawing: { () -> Bool in 20 | // Draw the thumbnail here. 21 | 22 | // Return true if the thumbnail was successfully drawn inside this block. 23 | return true 24 | }), nil) 25 | 26 | /* 27 | 28 | // Second way: Draw the thumbnail into a context passed to your block, set up with Core Graphics' coordinate system. 29 | handler(QLThumbnailReply(contextSize: request.maximumSize, drawing: { (context) -> Bool in 30 | // Draw the thumbnail here. 31 | 32 | // Return true if the thumbnail was successfully drawn inside this block. 33 | return true 34 | }), nil) 35 | 36 | // Third way: Set an image file URL. 37 | handler(QLThumbnailReply(imageFileURL: Bundle.main.url(forResource: "fileThumbnail", withExtension: "jpg")!), nil) 38 | 39 | */ 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MyToday/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyToday 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionMainStoryboard 26 | MainInterface 27 | NSExtensionPointIdentifier 28 | com.apple.widget-extension 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyToday/TodayViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodayViewController.swift 3 | // MyToday 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import NotificationCenter 11 | 12 | class TodayViewController: UIViewController, NCWidgetProviding { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | // Do any additional setup after loading the view from its nib. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { 25 | // Perform any setup necessary in order to update the view. 26 | 27 | // If an error is encountered, use NCUpdateResult.Failed 28 | // If there's no update required, use NCUpdateResult.NoData 29 | // If there's an update, use NCUpdateResult.NewData 30 | 31 | completionHandler(NCUpdateResult.newData) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /MyUnwantedCommunication/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MyUnwantedCommunication 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | ILClassificationExtensionSMSReportDestination 28 | +12345678910 29 | 30 | NSExtensionMainStoryboard 31 | MainInterface 32 | NSExtensionPointIdentifier 33 | com.apple.identitylookup.classification-ui 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /MyUnwantedCommunication/UnwantedCommunicationReportingExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnwantedCommunicationReportingExtension.swift 3 | // MyUnwantedCommunication 4 | // 5 | // Created by Jeff Kelley on 5/9/19. 6 | // Copyright © 2019 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import IdentityLookup 11 | import IdentityLookupUI 12 | 13 | class UnwantedCommunicationReportingExtension: ILClassificationUIExtensionViewController { 14 | 15 | override func viewDidAppear(_ animated: Bool) { 16 | super.viewDidAppear(animated) 17 | 18 | // Notify the system when you have completed gathering information 19 | // from the user and you are ready with a classification response 20 | self.extensionContext.isReadyForClassificationResponse = true 21 | } 22 | 23 | // Customize UI based on the classification request before the view is loaded 24 | override func prepare(for classificationRequest: ILClassificationRequest) { 25 | // Configure your views for the classification request 26 | } 27 | 28 | // Provide a classification response for the classification request 29 | override func classificationResponse(for request:ILClassificationRequest) -> ILClassificationResponse { 30 | return ILClassificationResponse(action: .none) 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /MyWatchIntents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyWatchIntents 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | IntentsSupported 28 | 29 | INSendMessageIntent 30 | INSearchForMessagesIntent 31 | 32 | 33 | NSExtensionPointIdentifier 34 | com.apple.intents-service 35 | NSExtensionPrincipalClass 36 | $(PRODUCT_MODULE_NAME).IntentHandler 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /MyXcodeSourceEditor/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyXcodeSourceEditor 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | XCSourceEditorCommandDefinitions 30 | 31 | 32 | XCSourceEditorCommandClassName 33 | $(PRODUCT_MODULE_NAME).SourceEditorCommand 34 | XCSourceEditorCommandIdentifier 35 | $(PRODUCT_BUNDLE_IDENTIFIER).SourceEditorCommand 36 | XCSourceEditorCommandName 37 | Source Editor Command 38 | 39 | 40 | XCSourceEditorExtensionPrincipalClass 41 | $(PRODUCT_MODULE_NAME).SourceEditorExtension 42 | 43 | NSExtensionPointIdentifier 44 | com.apple.dt.Xcode.extension.source-editor 45 | 46 | NSHumanReadableCopyright 47 | Copyright © 2017 Jeff Kelley. All rights reserved. 48 | 49 | 50 | -------------------------------------------------------------------------------- /MyXcodeSourceEditor/MyXcodeSourceEditor.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MyXcodeSourceEditor/SourceEditorCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorCommand.swift 3 | // MyXcodeSourceEditor 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XcodeKit 11 | 12 | class SourceEditorCommand: NSObject, XCSourceEditorCommand { 13 | 14 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void { 15 | // Implement your command here, invoking the completion handler when done. Pass it nil on success, and an NSError on failure. 16 | 17 | completionHandler(nil) 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /MyXcodeSourceEditor/SourceEditorExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorExtension.swift 3 | // MyXcodeSourceEditor 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XcodeKit 11 | 12 | class SourceEditorExtension: NSObject, XCSourceEditorExtension { 13 | 14 | /* 15 | func extensionDidFinishLaunching() { 16 | // If your extension needs to do any work at launch, implement this optional method. 17 | } 18 | */ 19 | 20 | /* 21 | var commandDefinitions: [[XCSourceEditorCommandDefinitionKey: Any]] { 22 | // If your extension needs to return a collection of command definitions that differs from those in its Info.plist, implement this optional property getter. 23 | return [] 24 | } 25 | */ 26 | 27 | } 28 | -------------------------------------------------------------------------------- /MyiMessage/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MyiMessage/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "60x45", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "60x45", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "ipad", 15 | "size" : "67x50", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "74x55", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "27x20", 25 | "idiom" : "universal", 26 | "scale" : "2x", 27 | "platform" : "ios" 28 | }, 29 | { 30 | "size" : "27x20", 31 | "idiom" : "universal", 32 | "scale" : "3x", 33 | "platform" : "ios" 34 | }, 35 | { 36 | "size" : "32x24", 37 | "idiom" : "universal", 38 | "scale" : "2x", 39 | "platform" : "ios" 40 | }, 41 | { 42 | "size" : "32x24", 43 | "idiom" : "universal", 44 | "scale" : "3x", 45 | "platform" : "ios" 46 | }, 47 | { 48 | "size" : "1024x768", 49 | "idiom" : "ios-marketing", 50 | "scale" : "1x", 51 | "platform" : "ios" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /MyiMessage/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MyiMessage 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionMainStoryboard 26 | MainInterface 27 | NSExtensionPointIdentifier 28 | com.apple.message-payload-provider 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Turducken 2 | What if we created iOS, macOS, and tvOS targets and then added *every single extension point* to them? This project is a stress test for Xcode and other auxiliary tools. 3 | 4 | [![Build Status](https://travis-ci.org/SlaunchaMan/Turducken.svg?branch=master)](https://travis-ci.org/SlaunchaMan/Turducken) 5 | -------------------------------------------------------------------------------- /Scanfile: -------------------------------------------------------------------------------- 1 | configuration "Debug" 2 | xcargs "CODE_SIGN_IDENTITY=\"\" DEVELOPMENT_TEAM=\"\"" 3 | -------------------------------------------------------------------------------- /Turducken.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Turducken.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Turducken.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Turducken/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Turducken/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Turducken/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Turducken/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Turducken/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Turducken 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /TurduckenMac/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // TurduckenMac 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /TurduckenMac/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /TurduckenMac/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 Jeff Kelley. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /TurduckenMac/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // TurduckenMac 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @available(OSX 10.10, *) 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // Do any additional setup after loading the view. 18 | } 19 | 20 | override var representedObject: Any? { 21 | didSet { 22 | // Update the view, if already loaded. 23 | } 24 | } 25 | 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /TurduckenMacTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TurduckenMacTests/TurduckenMacTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TurduckenMacTests.swift 3 | // TurduckenMacTests 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import TurduckenMac 11 | 12 | class TurduckenMacTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | XCTAssertTrue(true) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /TurduckenMacUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TurduckenMacUITests/TurduckenMacUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TurduckenMacUITests.swift 3 | // TurduckenMacUITests 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TurduckenMacUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | XCTAssertTrue(true) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "size" : "1280x768", 5 | "idiom" : "tv", 6 | "filename" : "App Icon - Large.imagestack", 7 | "role" : "primary-app-icon" 8 | }, 9 | { 10 | "size" : "400x240", 11 | "idiom" : "tv", 12 | "filename" : "App Icon - Small.imagestack", 13 | "role" : "primary-app-icon" 14 | }, 15 | { 16 | "size" : "2320x720", 17 | "idiom" : "tv", 18 | "filename" : "Top Shelf Image Wide.imageset", 19 | "role" : "top-shelf-image-wide" 20 | }, 21 | { 22 | "size" : "1920x720", 23 | "idiom" : "tv", 24 | "filename" : "Top Shelf Image.imageset", 25 | "role" : "top-shelf-image" 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TurduckenTV/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "landscape", 5 | "idiom" : "tv", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "11.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "landscape", 12 | "idiom" : "tv", 13 | "extent" : "full-screen", 14 | "minimum-system-version" : "9.0", 15 | "scale" : "1x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TurduckenTV/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /TurduckenTV/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIMainStoryboardFile 24 | Main 25 | UIRequiredDeviceCapabilities 26 | 27 | arm64 28 | 29 | UIUserInterfaceStyle 30 | Automatic 31 | 32 | 33 | -------------------------------------------------------------------------------- /TurduckenTV/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // TurduckenTV 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /TurduckenTVTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TurduckenTVTests/TurduckenTVTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TurduckenTVTests.swift 3 | // TurduckenTVTests 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import TurduckenTV 11 | 12 | class TurduckenTVTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | XCTAssertTrue(true) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /TurduckenTVUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TurduckenTVUITests/TurduckenTVUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TurduckenTVUITests.swift 3 | // TurduckenTVUITests 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TurduckenTVUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | XCTAssertTrue(true) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /TurduckenTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TurduckenTests/TurduckenTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TurduckenTests.swift 3 | // TurduckenTests 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Turducken 11 | 12 | class TurduckenTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | XCTAssertTrue(true) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /TurduckenUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TurduckenUITests/TurduckenUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TurduckenUITests.swift 3 | // TurduckenUITests 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TurduckenUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | XCTAssertTrue(true) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /TurduckenWatch Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /TurduckenWatch Extension/Assets.xcassets/Complication.complicationset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Circular.imageset", 6 | "role" : "circular" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "Extra Large.imageset", 11 | "role" : "extra-large" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "filename" : "Modular.imageset", 16 | "role" : "modular" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "filename" : "Utilitarian.imageset", 21 | "role" : "utilitarian" 22 | } 23 | ], 24 | "info" : { 25 | "version" : 1, 26 | "author" : "xcode" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TurduckenWatch Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /TurduckenWatch Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /TurduckenWatch Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /TurduckenWatch Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | TurduckenWatch Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | CLKComplicationPrincipalClass 24 | $(PRODUCT_MODULE_NAME).ComplicationController 25 | CLKComplicationSupportedFamilies 26 | 27 | CLKComplicationFamilyModularSmall 28 | CLKComplicationFamilyModularLarge 29 | CLKComplicationFamilyUtilitarianSmall 30 | CLKComplicationFamilyUtilitarianSmallFlat 31 | CLKComplicationFamilyUtilitarianLarge 32 | CLKComplicationFamilyCircularSmall 33 | CLKComplicationFamilyExtraLarge 34 | 35 | NSExtension 36 | 37 | NSExtensionAttributes 38 | 39 | WKAppBundleIdentifier 40 | com.slaunchaman.Turducken.watchkitapp 41 | 42 | NSExtensionPointIdentifier 43 | com.apple.watchkit 44 | 45 | WKExtensionDelegateClassName 46 | $(PRODUCT_MODULE_NAME).ExtensionDelegate 47 | 48 | 49 | -------------------------------------------------------------------------------- /TurduckenWatch Extension/InterfaceController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.swift 3 | // TurduckenWatch Extension 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | import Foundation 11 | 12 | 13 | class InterfaceController: WKInterfaceController { 14 | 15 | override func awake(withContext context: Any?) { 16 | super.awake(withContext: context) 17 | 18 | // Configure interface objects here. 19 | } 20 | 21 | override func willActivate() { 22 | // This method is called when watch view controller is about to be visible to user 23 | super.willActivate() 24 | } 25 | 26 | override func didDeactivate() { 27 | // This method is called when watch view controller is no longer visible 28 | super.didDeactivate() 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /TurduckenWatch Extension/NotificationController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationController.swift 3 | // TurduckenWatch Extension 4 | // 5 | // Created by Jeff Kelley on 3/16/17. 6 | // Copyright © 2017 Jeff Kelley. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | import Foundation 11 | import UserNotifications 12 | 13 | 14 | class NotificationController: WKUserNotificationInterfaceController { 15 | 16 | override init() { 17 | // Initialize variables here. 18 | super.init() 19 | 20 | // Configure interface objects here. 21 | } 22 | 23 | override func willActivate() { 24 | // This method is called when watch view controller is about to be visible to user 25 | super.willActivate() 26 | } 27 | 28 | override func didDeactivate() { 29 | // This method is called when watch view controller is no longer visible 30 | super.didDeactivate() 31 | } 32 | 33 | /* 34 | override func didReceive(_ notification: UNNotification, withCompletion completionHandler: @escaping (WKUserNotificationInterfaceType) -> Swift.Void) { 35 | // This method is called when a notification needs to be presented. 36 | // Implement it if you use a dynamic notification interface. 37 | // Populate your dynamic notification interface as quickly as possible. 38 | // 39 | // After populating your dynamic notification interface call the completion block. 40 | completionHandler(.custom) 41 | } 42 | */ 43 | } 44 | -------------------------------------------------------------------------------- /TurduckenWatch Extension/PushNotificationPayload.apns: -------------------------------------------------------------------------------- 1 | { 2 | "aps": { 3 | "alert": { 4 | "body": "Test message", 5 | "title": "Optional title" 6 | }, 7 | "category": "myCategory" 8 | }, 9 | 10 | "WatchKit Simulator Actions": [ 11 | { 12 | "title": "First Button", 13 | "identifier": "firstButtonAction" 14 | } 15 | ], 16 | 17 | "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." 18 | } 19 | -------------------------------------------------------------------------------- /TurduckenWatch/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "86x86", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "quickLook", 41 | "subtype" : "38mm" 42 | }, 43 | { 44 | "size" : "98x98", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "quickLook", 48 | "subtype" : "42mm" 49 | } 50 | ], 51 | "info" : { 52 | "version" : 1, 53 | "author" : "xcode" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /TurduckenWatch/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Turducken 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | UISupportedInterfaceOrientations 24 | 25 | UIInterfaceOrientationPortrait 26 | UIInterfaceOrientationPortraitUpsideDown 27 | 28 | WKCompanionAppBundleIdentifier 29 | com.slaunchaman.Turducken 30 | WKWatchKitApp 31 | 32 | 33 | 34 | --------------------------------------------------------------------------------