├── docs ├── img │ ├── gh.png │ ├── dash.png │ └── carat.png ├── docsets │ ├── KKCarPlayManager.tgz │ └── KKCarPlayManager.docset │ │ └── Contents │ │ ├── Resources │ │ ├── Documents │ │ │ ├── undocumented.json │ │ │ ├── img │ │ │ │ ├── gh.png │ │ │ │ ├── carat.png │ │ │ │ └── dash.png │ │ │ ├── badge.svg │ │ │ ├── js │ │ │ │ └── jazzy.js │ │ │ ├── search.json │ │ │ ├── Extensions.html │ │ │ ├── Enums.html │ │ │ ├── Structs.html │ │ │ ├── css │ │ │ │ ├── highlight.css │ │ │ │ └── jazzy.css │ │ │ ├── Extensions │ │ │ │ └── KKStaticContainerItem.html │ │ │ ├── Structs │ │ │ │ └── KKCarPlayItemsBuilder.html │ │ │ ├── Enums │ │ │ │ └── KKCarPlayManagerError.html │ │ │ ├── Classes │ │ │ │ ├── KKStaticContainerItem.html │ │ │ │ ├── KKCarPlayManager.html │ │ │ │ └── KKBasicContentItem.html │ │ │ └── Classes.html │ │ └── docSet.dsidx │ │ └── Info.plist ├── undocumented.json ├── badge.svg ├── js │ └── jazzy.js ├── search.json ├── Extensions.html ├── Enums.html ├── Structs.html ├── css │ ├── highlight.css │ └── jazzy.css ├── Extensions │ └── KKStaticContainerItem.html ├── Structs │ └── KKCarPlayItemsBuilder.html ├── Enums │ └── KKCarPlayManagerError.html ├── Classes │ ├── KKStaticContainerItem.html │ ├── KKCarPlayManager.html │ └── KKBasicContentItem.html └── Classes.html ├── Example ├── Podfile ├── Example │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Example.entitlements │ ├── PlayItem.swift │ ├── Info.plist │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── ViewController.swift │ └── AppDelegate.swift ├── Example.xcodeproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Example.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Podfile.lock ├── .gitignore ├── Tests ├── LinuxMain.swift └── KKCarPlayManagerTests │ ├── XCTestManifests.swift │ └── KKCarPlayManagerTests.swift ├── Sources ├── KKCarPlayManagerExtensions │ ├── KKCarPlayItemsBuilder.swift │ └── KKStaticContainerItemExtension.swift └── KKCarPlayManager │ ├── KKArrayExtensions.swift │ ├── KKStaticContainerItem.swift │ ├── KKBasicContentItem.swift │ └── KKCarPlayManager.swift ├── .travis.yml ├── .github └── workflows │ └── ci.yml ├── Package@swift-4.2.swift ├── Package@swift-5.0.swift ├── Package.swift ├── LICENSE ├── KKCarPlayManager.podspec └── README.md /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/img/gh.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/img/dash.png -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/img/carat.png -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | target 'Example' do 3 | pod 'KKCarPlayManager', :path => '../' 4 | end 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata 6 | .swiftpm 7 | Pods 8 | .vscode 9 | .idea -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/docsets/KKCarPlayManager.tgz -------------------------------------------------------------------------------- /docs/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | 4 | ], 5 | "source_directory": "/Users/zonble/Work/KKCarPlayManager" 6 | } -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import KKCarPlayManagerTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += KKCarPlayManagerTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | 4 | ], 5 | "source_directory": "/Users/zonble/Work/KKCarPlayManager" 6 | } -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/docsets/KKCarPlayManager.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KKBOX/KKCarPlayManager/HEAD/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/KKCarPlayManagerTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(KKCarPlayManagerTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Example/Example/Example.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.playable-content 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sources/KKCarPlayManagerExtensions/KKCarPlayItemsBuilder.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import KKCarPlayManager 3 | 4 | /// :nodoc: 5 | @_functionBuilder 6 | public struct KKCarPlayItemsBuilder { 7 | /// :nodoc: 8 | public static func buildBlock(_ items: KKBasicContentItem...) -> [KKBasicContentItem] { 9 | return items 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: swift 2 | osx_image: xcode11 3 | script: 4 | - swift package generate-xcodeproj 5 | - bash <(curl -s https://codecov.io/bash) -X xcodellvm 6 | - xcodebuild -scheme KKCarPlayManager-Package -destination 'platform=iOS Simulator,name=iPhone Xʀ,OS=13.0' -enableCodeCoverage YES build test 7 | after_success: 8 | - bash <(curl -s https://codecov.io/bash) 9 | -------------------------------------------------------------------------------- /Sources/KKCarPlayManager/KKArrayExtensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Array { 4 | func element(at index: Int) -> Iterator.Element? { 5 | switch index { 6 | case 0.. Int { 14 | return self.count > 0 ? self.count - 1 : 0 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push] 3 | 4 | jobs: 5 | build: 6 | name: Build 7 | runs-on: macOS-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - name: Build 11 | run: swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios12.1-simulator" 12 | working-directory: ./ 13 | -------------------------------------------------------------------------------- /Sources/KKCarPlayManagerExtensions/KKStaticContainerItemExtension.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import KKCarPlayManager 3 | 4 | /// :nodoc: 5 | extension KKStaticContainerItem { 6 | /// :nodoc: 7 | public convenience init(identifier: String, title: String, @KKCarPlayItemsBuilder builder:()->[KKBasicContentItem]) { 8 | self.init(identifier:identifier, title: title, children:builder()) 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - KKCarPlayManager (0.1.0): 3 | - KKCarPlayManager/KKCarPlayManager (= 0.1.0) 4 | - KKCarPlayManager/KKCarPlayManager (0.1.0) 5 | 6 | DEPENDENCIES: 7 | - KKCarPlayManager (from `../`) 8 | 9 | EXTERNAL SOURCES: 10 | KKCarPlayManager: 11 | :path: "../" 12 | 13 | SPEC CHECKSUMS: 14 | KKCarPlayManager: 30a1830b2902b62dac1ff28d4f31184365897f7a 15 | 16 | PODFILE CHECKSUM: fc55f97309a5993266f2ac5262bab1b28ae05619 17 | 18 | COCOAPODS: 1.7.4 19 | -------------------------------------------------------------------------------- /Tests/KKCarPlayManagerTests/KKCarPlayManagerTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import KKCarPlayManager 3 | 4 | final class KKCarPlayManagerTests: XCTestCase { 5 | func testExample() { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | // XCTAssertEqual(KKCarPlayManager().text, "Hello, World!") 10 | } 11 | 12 | static var allTests = [ 13 | ("testExample", testExample), 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /Package@swift-4.2.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.2 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "KKCarPlayManager", 7 | platforms: [ .iOS(.v8) ], 8 | products: [ 9 | .library( 10 | name: "KKCarPlayManager", 11 | targets: ["KKCarPlayManager"]), 12 | ], 13 | dependencies: [ 14 | // .package(url: /* package url */, from: "1.0.0"), 15 | ], 16 | targets: [ 17 | .target( 18 | name: "KKCarPlayManager", 19 | dependencies: []), 20 | .testTarget( 21 | name: "KKCarPlayManagerTests", 22 | dependencies: ["KKCarPlayManager"]), 23 | ], 24 | swiftLanguageVersions: [.v4, .v4_2, .v5] 25 | ) 26 | -------------------------------------------------------------------------------- /Package@swift-5.0.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "KKCarPlayManager", 7 | platforms: [ .iOS(.v8) ], 8 | products: [ 9 | .library( 10 | name: "KKCarPlayManager", 11 | targets: ["KKCarPlayManager"]), 12 | ], 13 | dependencies: [ 14 | // .package(url: /* package url */, from: "1.0.0"), 15 | ], 16 | targets: [ 17 | .target( 18 | name: "KKCarPlayManager", 19 | dependencies: []), 20 | .testTarget( 21 | name: "KKCarPlayManagerTests", 22 | dependencies: ["KKCarPlayManager"]), 23 | ], 24 | swiftLanguageVersions: [.v4, .v4_2, .v5] 25 | ) 26 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.kkcarplaymanager 7 | CFBundleName 8 | KKCarPlayManager 9 | DocSetPlatformFamily 10 | kkcarplaymanager 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sources/KKCarPlayManager/KKStaticContainerItem.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A container item with static children. 4 | public class KKStaticContainerItem: KKBasicContentItem { 5 | 6 | private var staticChildren: [KKBasicContentItem] 7 | 8 | /// Creates an instance. 9 | /// 10 | /// - Parameter identifier: Identifier of the item. 11 | /// - Parameter title: Title of the item. 12 | /// - Parameter children: Children of the item. 13 | public init(identifier: String, title: String, children: [KKBasicContentItem]) { 14 | self.staticChildren = children 15 | super.init(identifier: identifier) 16 | self.title = title 17 | self.children = children 18 | isPlayable = false 19 | isContainer = true 20 | } 21 | 22 | /// :nodoc: 23 | public override func loadChildren(callback: @escaping (Error?) -> Void) throws { 24 | self.children = self.staticChildren 25 | callback(nil) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "KKCarPlayManager", 7 | platforms: [ .iOS(.v8) ], 8 | products: [ 9 | .library( 10 | name: "KKCarPlayManager", 11 | targets: ["KKCarPlayManager"]), 12 | .library( 13 | name: "KKCarPlayManagerExtension", 14 | targets: ["KKCarPlayManagerExtensions"]), 15 | ], 16 | dependencies: [ 17 | // .package(url: /* package url */, from: "1.0.0"), 18 | ], 19 | targets: [ 20 | .target( 21 | name: "KKCarPlayManager", 22 | dependencies: []), 23 | .target( 24 | name: "KKCarPlayManagerExtensions", 25 | dependencies: ["KKCarPlayManager"]), 26 | .testTarget( 27 | name: "KKCarPlayManagerTests", 28 | dependencies: ["KKCarPlayManager"]), 29 | ], 30 | swiftLanguageVersions: [.v4, .v4_2, .v5] 31 | ) 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 KKBOX 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 | -------------------------------------------------------------------------------- /KKCarPlayManager.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'KKCarPlayManager' 3 | s.version = '0.1.3' 4 | s.summary = 'Helps to implement an CarPlay audio app.' 5 | s.description = <<-DESC 6 | KKCarPlayManager helps you to build the tree of the content items to let users to browsw on a CarPlay audio app. 7 | DESC 8 | 9 | s.homepage = 'https://github.com/KKBOX/KKCarPlayManager' 10 | s.license = { :type => 'MIT', :file => 'LICENSE' } 11 | s.author = { 'zonble' => 'zonble@gmail.com' } 12 | s.source = { :git => 'https://github.com/KKBOX/KKCarPlayManager.git', :tag => s.version.to_s } 13 | 14 | s.ios.deployment_target = '8.0' 15 | s.swift_versions = ['4.2', '5.0', '5.1'] 16 | 17 | s.subspec 'KKCarPlayManager' do |sp| 18 | sp.source_files = 'Sources/KKCarPlayManager/**/*' 19 | end 20 | 21 | s.subspec 'KKCarPlayManagerExtensions' do |sp| 22 | sp.source_files = 'Sources/KKCarPlayManagerExtensions/**/*' 23 | sp.dependency 'KKCarPlayManager/KKCarPlayManager' 24 | end 25 | 26 | s.frameworks = 'MediaPlayer' 27 | s.default_subspec = 'KKCarPlayManager' 28 | 29 | end 30 | -------------------------------------------------------------------------------- /docs/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 100% 23 | 24 | 25 | 100% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 100% 23 | 24 | 25 | 100% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Example/Example/PlayItem.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import KKCarPlayManager 3 | import AVFoundation 4 | import MediaPlayer 5 | 6 | enum PlayItemError: Error { 7 | case noURL 8 | } 9 | 10 | class PlayItem: KKBasicContentItem { 11 | 12 | var url: URL? 13 | 14 | public init(identifier: String, title: String, url urlString: String) { 15 | super.init(identifier: identifier) 16 | self.title = title 17 | url = URL(string: urlString) 18 | isContainer = false 19 | isPlayable = true 20 | } 21 | 22 | override func play(callback: @escaping (Error?) -> Void) throws -> Bool { 23 | guard let url = url else { 24 | callback(PlayItemError.noURL) 25 | return false 26 | } 27 | appDelegate().player.replaceCurrentItem(with: AVPlayerItem(url: url)) 28 | appDelegate().player.play() 29 | MPNowPlayingInfoCenter.default().nowPlayingInfo = [ 30 | MPNowPlayingInfoPropertyPlaybackRate: 1, 31 | MPMediaItemPropertyTitle: self.title ?? "", 32 | MPMediaItemPropertyArtist: "zonble", 33 | MPMediaItemPropertyAlbumTitle: "zonble", 34 | MPNowPlayingInfoPropertyElapsedPlaybackTime: 0, 35 | MPMediaItemPropertyPlaybackDuration: 100, 36 | MPNowPlayingInfoPropertyPlaybackQueueCount: 1, 37 | MPNowPlayingInfoPropertyPlaybackQueueIndex: 0 38 | ] 39 | callback(nil) 40 | return true 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/KKCarPlayManager/KKBasicContentItem.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import MediaPlayer 3 | 4 | /// KKBOX's own subclass of MPContentItem. 5 | /// 6 | /// Please subclass the class and override `loadChildren(callback:)` or 7 | /// `play(callback:)` for your own need. 8 | open class KKBasicContentItem: MPContentItem { 9 | 10 | /// Childten items of the item. We use this property to build a tree and 11 | /// feed item on each index path to MPPlayableContentManager. 12 | open var children: [KKBasicContentItem]? 13 | 14 | /// To load the children of the node. 15 | /// 16 | /// - Parameters: 17 | /// - callback: the callback function. It contains an error object if it 18 | /// encounters any error while loading. 19 | open func loadChildren(callback: @escaping (Error?) -> Void) throws { 20 | if self.isContainer == false { 21 | fatalError("Not a container.") 22 | } 23 | fatalError("Not implemented.") 24 | } 25 | 26 | /// To play the media mapping to the item. 27 | open func play(callback: @escaping (Error?) -> Void) throws -> Bool { 28 | fatalError("Not implemented") 29 | } 30 | } 31 | 32 | extension KKBasicContentItem { 33 | 34 | /// Apply an image to the current item. 35 | public func apply(image: UIImage?) -> Self { 36 | if let image = image { 37 | self.artwork = MPMediaItemArtwork(image: image) 38 | } else { 39 | self.artwork = nil 40 | } 41 | return self 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | 42 | // Dumb down quotes within code blocks that delimit strings instead of quotations 43 | // https://github.com/realm/jazzy/issues/714 44 | $("code q").replaceWith(function () { 45 | return ["\"", $(this).contents(), "\""]; 46 | }); 47 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | 42 | // Dumb down quotes within code blocks that delimit strings instead of quotations 43 | // https://github.com/realm/jazzy/issues/714 44 | $("code q").replaceWith(function () { 45 | return ["\"", $(this).contents(), "\""]; 46 | }); 47 | -------------------------------------------------------------------------------- /Example/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | UIBackgroundModes 24 | 25 | audio 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/Example/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 | -------------------------------------------------------------------------------- /Example/Example/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" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Example/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import AVFoundation 3 | import MediaPlayer 4 | 5 | typealias PlayableItem = (String, String) 6 | 7 | class ViewController: UITableViewController { 8 | var items:[[PlayableItem]] = [ 9 | [ 10 | ("天狗", "https://zonble.net/MIDI/tiengo.mp3"), 11 | ("回向", "https://zonble.net/MIDI/return.mp3")], 12 | [ 13 | ("orz", "https://zonble.net/MIDI/orz.mp3"), 14 | ("藿香薊", "https://zonble.net/MIDI/ageratum_conyzoides.mp3")] 15 | ] 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") 20 | self.title = "KKCarPlayManager Example" 21 | } 22 | 23 | override func numberOfSections(in tableView: UITableView) -> Int { 24 | return items.count 25 | } 26 | 27 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 28 | return items[section].count 29 | } 30 | 31 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 32 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 33 | cell.textLabel?.text = items[indexPath.section][indexPath.row].0 34 | return cell 35 | } 36 | 37 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 38 | tableView.deselectRow(at: indexPath, animated: true) 39 | let urlString = items[indexPath.section][indexPath.row].1 40 | let name = items[indexPath.section][indexPath.row].0 41 | if let url = URL(string: urlString) { 42 | appDelegate().player.replaceCurrentItem(with: AVPlayerItem(url: url)) 43 | appDelegate().player.play() 44 | MPNowPlayingInfoCenter.default().nowPlayingInfo = [ 45 | MPNowPlayingInfoPropertyPlaybackRate: 1, 46 | MPMediaItemPropertyTitle: name, 47 | MPMediaItemPropertyArtist: "zonble", 48 | MPMediaItemPropertyAlbumTitle: "zonble", 49 | MPNowPlayingInfoPropertyElapsedPlaybackTime: 0, 50 | MPMediaItemPropertyPlaybackDuration: 100, 51 | MPNowPlayingInfoPropertyPlaybackQueueCount: 1, 52 | MPNowPlayingInfoPropertyPlaybackQueueIndex: 0 53 | ] 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Example/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import KKCarPlayManager 3 | import MediaPlayer 4 | import AVFoundation 5 | 6 | func appDelegate() -> AppDelegate { 7 | return UIApplication.shared.delegate as! AppDelegate 8 | } 9 | 10 | @UIApplicationMain 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | var window: UIWindow? 13 | var manager: KKCarPlayManager? 14 | var player = AVPlayer() 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | 18 | MPRemoteCommandCenter.shared().playCommand.addTarget { event in 19 | return .success 20 | } 21 | MPRemoteCommandCenter.shared().pauseCommand.addTarget { event in 22 | return .success 23 | } 24 | MPRemoteCommandCenter.shared().stopCommand.addTarget { event in 25 | return .success 26 | } 27 | MPRemoteCommandCenter.shared().togglePlayPauseCommand.addTarget { event in 28 | return .success 29 | } 30 | MPRemoteCommandCenter.shared().previousTrackCommand.addTarget { event in 31 | return .success 32 | } 33 | MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { event in 34 | return .success 35 | } 36 | application.beginReceivingRemoteControlEvents() 37 | 38 | 39 | let rooNode = KKStaticContainerItem(identifier: "root", title: "Root", children: [ 40 | KKStaticContainerItem(identifier: "folder1", title: "Folder 1", children: [ 41 | PlayItem(identifier: "Song_1_1", title: "天狗", url: "https://zonble.net/MIDI/tiengo.mp3"), 42 | PlayItem(identifier: "Song_1_2", title: "回向", url: "https://zonble.net/MIDI/return.mp3"), 43 | ]), 44 | KKStaticContainerItem(identifier: "folder_2", title: "Folder 2", children: [ 45 | PlayItem(identifier: "Song_2_1", title: "orz", url: "https://zonble.net/MIDI/orz.mp3"), 46 | PlayItem(identifier: "Song_2_2", title: "藿香薊", url: "https://zonble.net/MIDI/ageratum_conyzoides.mp3") 47 | ]), 48 | ] 49 | ) 50 | manager = KKCarPlayManager(rootNode: rooNode) 51 | manager?.activate() 52 | 53 | try? AVAudioSession.sharedInstance().setCategory(.playback) 54 | try? AVAudioSession.sharedInstance().setActive(true, options: []) 55 | 56 | let vc = ViewController(style: .grouped) 57 | let nav = UINavigationController(rootViewController: vc) 58 | window = UIWindow(frame: UIScreen.main.bounds) 59 | window?.rootViewController = nav 60 | window?.makeKeyAndVisible() 61 | 62 | return true 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /docs/search.json: -------------------------------------------------------------------------------- 1 | {"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO12itemNotExistyA2CmF":{"name":"itemNotExist","abstract":"

The item does not exist.

","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO7messageyACSScACmF":{"name":"message(_:)","abstract":"

An error with a message.

","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html":{"name":"KKCarPlayManagerError","abstract":"

The error used in KKCarPlayManager.

"},"Classes/KKStaticContainerItem.html#/s:16KKCarPlayManager21KKStaticContainerItemC10identifier5title8childrenACSS_SSSayAA014KKBasicContentF0CGtcfc":{"name":"init(identifier:title:children:)","abstract":"

Creates an instance.

","parent_name":"KKStaticContainerItem"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8activateyyF":{"name":"activate()","abstract":"

Set the data source and delegate of MPPlayableContentManager to","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC10deactivateyyF":{"name":"deactivate()","abstract":"

Set the data source and delegate of MPPlayableContentManager to nil.

","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8rootNodeAbA18KKBasicContentItemC_tcfc":{"name":"init(rootNode:)","abstract":"

Creates a new instance.

","parent_name":"KKCarPlayManager"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC8childrenSayACGSgvp":{"name":"children","abstract":"

Childten items of the item. We use this property to build a tree and","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC12loadChildren8callbackyys5Error_pSgc_tKF":{"name":"loadChildren(callback:)","abstract":"

To load the children of the node.

","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC4play8callbackSbys5Error_pSgc_tKF":{"name":"play(callback:)","abstract":"

To play the media mapping to the item.

","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC5apply5imageACSo7UIImageCSg_tF":{"name":"apply(image:)","abstract":"

Apply an image to the current item.

","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html":{"name":"KKBasicContentItem","abstract":"

KKBOX’s own subclass of MPContentItem.

"},"Classes/KKCarPlayManager.html":{"name":"KKCarPlayManager","abstract":"

A class helps your to build a tree structure of playable items for CarPlay.

"},"Classes/KKStaticContainerItem.html":{"name":"KKStaticContainerItem","abstract":"

A container item with static children.

"},"Classes.html":{"name":"Classes","abstract":"

The following classes are available globally.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"}} -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/search.json: -------------------------------------------------------------------------------- 1 | {"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO12itemNotExistyA2CmF":{"name":"itemNotExist","abstract":"

The item does not exist.

","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO7messageyACSScACmF":{"name":"message(_:)","abstract":"

An error with a message.

","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html":{"name":"KKCarPlayManagerError","abstract":"

The error used in KKCarPlayManager.

"},"Classes/KKStaticContainerItem.html#/s:16KKCarPlayManager21KKStaticContainerItemC10identifier5title8childrenACSS_SSSayAA014KKBasicContentF0CGtcfc":{"name":"init(identifier:title:children:)","abstract":"

Creates an instance.

","parent_name":"KKStaticContainerItem"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8activateyyF":{"name":"activate()","abstract":"

Set the data source and delegate of MPPlayableContentManager to","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC10deactivateyyF":{"name":"deactivate()","abstract":"

Set the data source and delegate of MPPlayableContentManager to nil.

","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8rootNodeAbA18KKBasicContentItemC_tcfc":{"name":"init(rootNode:)","abstract":"

Creates a new instance.

","parent_name":"KKCarPlayManager"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC8childrenSayACGSgvp":{"name":"children","abstract":"

Childten items of the item. We use this property to build a tree and","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC12loadChildren8callbackyys5Error_pSgc_tKF":{"name":"loadChildren(callback:)","abstract":"

To load the children of the node.

","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC4play8callbackSbys5Error_pSgc_tKF":{"name":"play(callback:)","abstract":"

To play the media mapping to the item.

","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC5apply5imageACSo7UIImageCSg_tF":{"name":"apply(image:)","abstract":"

Apply an image to the current item.

","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html":{"name":"KKBasicContentItem","abstract":"

KKBOX’s own subclass of MPContentItem.

"},"Classes/KKCarPlayManager.html":{"name":"KKCarPlayManager","abstract":"

A class helps your to build a tree structure of playable items for CarPlay.

"},"Classes/KKStaticContainerItem.html":{"name":"KKStaticContainerItem","abstract":"

A container item with static children.

"},"Classes.html":{"name":"Classes","abstract":"

The following classes are available globally.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"}} -------------------------------------------------------------------------------- /docs/Extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extensions Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

Extensions

74 |

The following extensions are available globally.

75 | 76 |
77 |
78 |
79 | 100 |
101 |
102 |
103 | 107 |
108 |
109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docs/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enumerations Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

Enumerations

58 |

The following enumerations are available globally.

59 | 60 |
61 |
62 |
63 |
    64 |
  • 65 |
    66 | 67 | 68 | 69 | KKCarPlayManagerError 70 | 71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 |

    The error used in KKCarPlayManager.

    78 | 79 | See more 80 |
    81 |
    82 |

    Declaration

    83 |
    84 |

    Swift

    85 |
    public enum KKCarPlayManagerError : Error, LocalizedError
    86 | 87 |
    88 |
    89 |
    90 |
    91 |
  • 92 |
93 |
94 |
95 |
96 | 100 |
101 |
102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extensions Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

Extensions

74 |

The following extensions are available globally.

75 | 76 |
77 |
78 |
79 | 100 |
101 |
102 |
103 | 107 |
108 |
109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enumerations Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

Enumerations

58 |

The following enumerations are available globally.

59 | 60 |
61 |
62 |
63 |
    64 |
  • 65 |
    66 | 67 | 68 | 69 | KKCarPlayManagerError 70 | 71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 |

    The error used in KKCarPlayManager.

    78 | 79 | See more 80 |
    81 |
    82 |

    Declaration

    83 |
    84 |

    Swift

    85 |
    public enum KKCarPlayManagerError : Error, LocalizedError
    86 | 87 |
    88 |
    89 |
    90 |
    91 |
  • 92 |
93 |
94 |
95 |
96 | 100 |
101 |
102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /docs/Structs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Structures Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

Structures

74 |

The following structures are available globally.

75 | 76 |
77 |
78 |
79 |
    80 |
  • 81 |
    82 | 83 | 84 | 85 | KKCarPlayItemsBuilder 86 | 87 |
    88 |
    89 |
    90 |
    91 |
    92 |
    93 |

    Undocumented

    94 | 95 | See more 96 |
    97 |
    98 |

    Declaration

    99 |
    100 |

    Swift

    101 |
    public struct KKCarPlayItemsBuilder
    102 | 103 |
    104 |
    105 |
    106 |
    107 |
  • 108 |
109 |
110 |
111 |
112 | 116 |
117 |
118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Structs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Structures Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

Structures

74 |

The following structures are available globally.

75 | 76 |
77 |
78 |
79 |
    80 |
  • 81 |
    82 | 83 | 84 | 85 | KKCarPlayItemsBuilder 86 | 87 |
    88 |
    89 |
    90 |
    91 |
    92 |
    93 |

    Undocumented

    94 | 95 | See more 96 |
    97 |
    98 |

    Declaration

    99 |
    100 |

    Swift

    101 |
    public struct KKCarPlayItemsBuilder
    102 | 103 |
    104 |
    105 |
    106 |
    107 |
  • 108 |
109 |
110 |
111 |
112 | 116 |
117 |
118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /Sources/KKCarPlayManager/KKCarPlayManager.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import MediaPlayer 3 | 4 | /// The error used in `KKCarPlayManager`. 5 | public enum KKCarPlayManagerError : Error, LocalizedError { 6 | /// The item does not exist. 7 | case itemNotExist 8 | /// An error with a message. 9 | case message(String) 10 | 11 | /// :nodoc: 12 | public var errorDescription: String? { 13 | switch self { 14 | case .itemNotExist: 15 | return "The item does not exist." 16 | case .message(let message): 17 | return message 18 | } 19 | } 20 | } 21 | 22 | /// A class helps your to build a tree structure of playable items for CarPlay. 23 | public class KKCarPlayManager: NSObject { 24 | 25 | /// Set the data source and delegate of MPPlayableContentManager to 26 | /// the current instance of KKCarPlayManager. 27 | public func activate() { 28 | MPPlayableContentManager.shared().dataSource = self 29 | MPPlayableContentManager.shared().delegate = self 30 | MPPlayableContentManager.shared().beginUpdates() 31 | MPPlayableContentManager.shared().endUpdates() 32 | } 33 | 34 | /// Set the data source and delegate of MPPlayableContentManager to nil. 35 | public func deactivate() { 36 | MPPlayableContentManager.shared().dataSource = nil 37 | MPPlayableContentManager.shared().delegate = nil 38 | } 39 | 40 | /// The root node of KKCarPlayManager. 41 | public final var rootNode: KKBasicContentItem { 42 | didSet { 43 | MPPlayableContentManager.shared().beginUpdates() 44 | MPPlayableContentManager.shared().endUpdates() 45 | } 46 | } 47 | final var currentPlaybackCallback: ((Error?) -> Void)? 48 | 49 | /// Creates a new instance. 50 | /// - Parameter rootNode: The root node. 51 | public init(rootNode: KKBasicContentItem) { 52 | self.rootNode = rootNode 53 | super.init() 54 | } 55 | 56 | 57 | /// Travel through the tree to find a specific node by giving the 58 | /// index path of the node. 59 | /// 60 | /// - parameter indexPath: Index path of the node. 61 | /// - returns: The node found in the tree. 62 | fileprivate func travel(_ indexPath: IndexPath) -> KKBasicContentItem? { 63 | if indexPath.count == 0 { 64 | return self.rootNode 65 | } 66 | var node: KKBasicContentItem? = self.rootNode 67 | for i in 0.. Bool { 76 | let error = KKCarPlayManagerError.message(message) 77 | return self.commitCurrentPlaybackCallback(error) 78 | } 79 | 80 | /// :nodoc: 81 | @objc public final func commitCurrentPlaybackCallback(_ error: Error?) -> Bool { 82 | NSObject.cancelPreviousPerformRequests(withTarget: self) 83 | if let callback = currentPlaybackCallback { 84 | DispatchQueue.global(qos: .default).async { 85 | callback(error) 86 | } 87 | currentPlaybackCallback = nil 88 | return true 89 | } 90 | return false 91 | } 92 | 93 | /// :nodoc: 94 | public final func delayedCommitCurrentPlaybackCallbackWithourError() { 95 | NSObject.cancelPreviousPerformRequests(withTarget: self) 96 | self.perform(#selector(KKCarPlayManager.commitCurrentPlaybackCallback(_:)), with: nil, afterDelay: 0.5) 97 | } 98 | 99 | } 100 | 101 | extension KKCarPlayManager: MPPlayableContentDataSource { 102 | /// :nodoc: 103 | public final func numberOfChildItems(at indexPath: IndexPath) -> Int { 104 | let node = self.travel(indexPath) 105 | return node?.children?.count ?? 0 106 | } 107 | 108 | /// :nodoc: 109 | public final func contentItem(at indexPath: IndexPath) -> MPContentItem? { 110 | let node = self.travel(indexPath) 111 | return node 112 | } 113 | 114 | /// :nodoc: 115 | @objc(beginLoadingChildItemsAtIndexPath:completionHandler:) 116 | public final func beginLoadingChildItems(at indexPath: IndexPath, completionHandler: @escaping (Error?) -> ()) { 117 | func continueLoadingChildren() { 118 | guard let node = self.travel(indexPath) else { 119 | completionHandler(KKCarPlayManagerError.itemNotExist) 120 | return 121 | } 122 | if node.children != nil { 123 | for item in node.children! { 124 | item.children = nil 125 | } 126 | completionHandler(nil) 127 | return 128 | } 129 | 130 | do { 131 | try node.loadChildren { error in 132 | if let error = error { 133 | completionHandler(error) 134 | return 135 | } 136 | completionHandler(nil) 137 | } 138 | } catch { 139 | completionHandler(node.children != nil ? nil : error) 140 | } 141 | } 142 | 143 | continueLoadingChildren() 144 | } 145 | 146 | } 147 | 148 | extension KKCarPlayManager: MPPlayableContentDelegate { 149 | /// :nodoc: 150 | public final func playableContentManager(_ contentManager: MPPlayableContentManager, initiatePlaybackOfContentItemAt indexPath: IndexPath, completionHandler: @escaping (Error?) -> Void) { 151 | DispatchQueue.main.async { [weak self] in 152 | if let strongSelf = self { 153 | NSObject.cancelPreviousPerformRequests(withTarget: strongSelf) 154 | } 155 | guard let currentNode = self?.travel(indexPath) else { 156 | completionHandler(KKCarPlayManagerError.itemNotExist) 157 | return 158 | } 159 | 160 | self?.currentPlaybackCallback?(nil) 161 | self?.currentPlaybackCallback = completionHandler 162 | do { 163 | let shouldCleanCachedCallback = try currentNode.play(callback: completionHandler) 164 | if shouldCleanCachedCallback { 165 | self?.currentPlaybackCallback = nil 166 | } 167 | } catch { 168 | self?.currentPlaybackCallback?(error as NSError) 169 | self?.currentPlaybackCallback = nil 170 | } 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /docs/Extensions/KKStaticContainerItem.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKStaticContainerItem Extension Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

KKStaticContainerItem

74 | 75 |
76 |
77 |
78 |
    79 |
  • 80 |
    81 | 82 | 83 | 84 | init(identifier:title:builder:) 85 | 86 |
    87 |
    88 |
    89 |
    90 |
    91 |
    92 |

    Undocumented

    93 | 94 |
    95 |
    96 |

    Declaration

    97 |
    98 |

    Swift

    99 |
    public convenience init(identifier: String, title: String, builder: () -> [KKBasicContentItem])
    100 | 101 |
    102 |
    103 |
    104 |
    105 |
  • 106 |
107 |
108 |
109 |
110 | 114 |
115 |
116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Extensions/KKStaticContainerItem.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKStaticContainerItem Extension Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

KKStaticContainerItem

74 | 75 |
76 |
77 |
78 |
    79 |
  • 80 |
    81 | 82 | 83 | 84 | init(identifier:title:builder:) 85 | 86 |
    87 |
    88 |
    89 |
    90 |
    91 |
    92 |

    Undocumented

    93 | 94 |
    95 |
    96 |

    Declaration

    97 |
    98 |

    Swift

    99 |
    public convenience init(identifier: String, title: String, builder: () -> [KKBasicContentItem])
    100 | 101 |
    102 |
    103 |
    104 |
    105 |
  • 106 |
107 |
108 |
109 |
110 | 114 |
115 |
116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /docs/Structs/KKCarPlayItemsBuilder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKCarPlayItemsBuilder Structure Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

KKCarPlayItemsBuilder

74 |
75 |
76 |
public struct KKCarPlayItemsBuilder
77 | 78 |
79 |
80 |

Undocumented

81 | 82 |
83 |
84 |
85 |
    86 |
  • 87 |
    88 | 89 | 90 | 91 | buildBlock(_:) 92 | 93 |
    94 |
    95 |
    96 |
    97 |
    98 |
    99 |

    Undocumented

    100 | 101 |
    102 |
    103 |

    Declaration

    104 |
    105 |

    Swift

    106 |
    public static func buildBlock(_ items: KKBasicContentItem...) -> [KKBasicContentItem]
    107 | 108 |
    109 |
    110 |
    111 |
    112 |
  • 113 |
114 |
115 |
116 |
117 | 121 |
122 |
123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Structs/KKCarPlayItemsBuilder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKCarPlayItemsBuilder Structure Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (68% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 70 |
71 |
72 |
73 |

KKCarPlayItemsBuilder

74 |
75 |
76 |
public struct KKCarPlayItemsBuilder
77 | 78 |
79 |
80 |

Undocumented

81 | 82 |
83 |
84 |
85 |
    86 |
  • 87 |
    88 | 89 | 90 | 91 | buildBlock(_:) 92 | 93 |
    94 |
    95 |
    96 |
    97 |
    98 |
    99 |

    Undocumented

    100 | 101 |
    102 |
    103 |

    Declaration

    104 |
    105 |

    Swift

    106 |
    public static func buildBlock(_ items: KKBasicContentItem...) -> [KKBasicContentItem]
    107 | 108 |
    109 |
    110 |
    111 |
    112 |
  • 113 |
114 |
115 |
116 |
117 | 121 |
122 |
123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/Enums/KKCarPlayManagerError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKCarPlayManagerError Enumeration Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKCarPlayManagerError

58 |
59 |
60 |
public enum KKCarPlayManagerError : Error, LocalizedError
61 | 62 |
63 |
64 |

The error used in KKCarPlayManager.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | itemNotExist 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    The item does not exist.

    84 | 85 |
    86 |
    87 |

    Declaration

    88 |
    89 |

    Swift

    90 |
    case itemNotExist
    91 | 92 |
    93 |
    94 |
    95 |
    96 |
  • 97 |
  • 98 |
    99 | 100 | 101 | 102 | message(_:) 103 | 104 |
    105 |
    106 |
    107 |
    108 |
    109 |
    110 |

    An error with a message.

    111 | 112 |
    113 |
    114 |

    Declaration

    115 |
    116 |

    Swift

    117 |
    case message(String)
    118 | 119 |
    120 |
    121 |
    122 |
    123 |
  • 124 |
125 |
126 |
127 |
128 | 132 |
133 |
134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Enums/KKCarPlayManagerError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKCarPlayManagerError Enumeration Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKCarPlayManagerError

58 |
59 |
60 |
public enum KKCarPlayManagerError : Error, LocalizedError
61 | 62 |
63 |
64 |

The error used in KKCarPlayManager.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | itemNotExist 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    The item does not exist.

    84 | 85 |
    86 |
    87 |

    Declaration

    88 |
    89 |

    Swift

    90 |
    case itemNotExist
    91 | 92 |
    93 |
    94 |
    95 |
    96 |
  • 97 |
  • 98 |
    99 | 100 | 101 | 102 | message(_:) 103 | 104 |
    105 |
    106 |
    107 |
    108 |
    109 |
    110 |

    An error with a message.

    111 | 112 |
    113 |
    114 |

    Declaration

    115 |
    116 |

    Swift

    117 |
    case message(String)
    118 | 119 |
    120 |
    121 |
    122 |
    123 |
  • 124 |
125 |
126 |
127 |
128 | 132 |
133 |
134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KKCarPlayManager 2 | 3 | [![Actions Status](https://github.com/KKBOX/KKCarPlayManager/workflows/Build/badge.svg)](https://github.com/KKBOX/KKCarPlayManager/actions) 4 | [![CocoaPods](http://img.shields.io/cocoapods/v/KKCarPlayManager.svg?style=flat)](http://cocoapods.org/pods/KKCarPlayManager) 5 | [![Support](https://img.shields.io/badge/iOS-8-blue.svg)](https://www.apple.com/tw/ios) 6 | 7 | 2019 © KKBOX. 8 | 9 | **KKCarPlayManager** provides a simple, clear and declarative way to implement 10 | the functionalities of [CarPlay](https://www.apple.com/ios/carplay/). 11 | 12 | ## Requirement 13 | 14 | - Xcode 15 | - Swift 4.2 or above 16 | - iOS 8.0 or above 17 | 18 | ## Installation 19 | 20 | You can install the package via Swift Package Manager or CocoaPods. 21 | 22 | ### CocoaPods 23 | 24 | Add `KKCarPlayManager` to your pod file, then run `pod install`. 25 | 26 | ### Swift Package Manager 27 | 28 | Just add `https://github.com/KKBOX/KKCarPlayManager.git` to your `Package.swift` 29 | file, or, you can add the package in Xcode 11 by selecting "File" -> "Swift 30 | Packages" -> "Add Package Dependency". 31 | 32 | ## Example 33 | 34 | The project has an example project. Go to the `Example` folder, run `pod install`, 35 | open `Example.xcworkspace`, build and run the example app. 36 | 37 | ## Getting Started 38 | 39 | Apple does not allow a CarPlay audio app to customize user interface./ You don't 40 | call any method on CarPlay, but let 41 | [MPPlayableContentManager](https://developer.apple.com/documentation/mediaplayer/mpplayablecontentmanager) 42 | to call you, discover your contents, and list them in a structured table user 43 | interface. 44 | 45 | KKCarPlayManager helps you to build your contents into a tree to be discovered. 46 | KKCarPlayManager already implemented the data source and delegate of 47 | MPPlayableContentManager for you, and all you need to do is to give 48 | KKCarPlayManager a root node and its subnodes. For example: 49 | 50 | ``` swift 51 | // Import required modules. 52 | 53 | import KKCarPlayManager 54 | import MediaPlayer 55 | import AVFoundation 56 | 57 | // You should set at least one command of MPRemoteCommandCenter, otherwise 58 | // MPPlayableContentManager won't call it data source and delegate. 59 | MPRemoteCommandCenter.shared().playCommand.addTarget { event in 60 | return .success 61 | } 62 | 63 | // Create a root node. 64 | let rooNode = KKStaticContainerItem(identifier: "root", title: "Root", children: [ 65 | KKStaticContainerItem(identifier: "folder1", title: "Folder 1", children: [ 66 | PlayItem(identifier: "Song_1_1", title: "Song name", url: "song URL..."), 67 | PlayItem(identifier: "Song_1_2", title: "Song name", url: "song URL..."), 68 | ]), 69 | KKStaticContainerItem(identifier: "folder_2", title: "Folder 2", children: [ 70 | PlayItem(identifier: "Song_2_1", title: "Song name", url: "song URL..."), 71 | PlayItem(identifier: "Song_2_2", title: "Song name", url: "song URL...") 72 | ]), 73 | ] 74 | ) 75 | 76 | // Create your manager. 77 | manager = KKCarPlayManager(rootNode: rooNode) 78 | 79 | // Sets the data source and delegate of MPPlayableContentManager to the manager. 80 | manager?.activate() 81 | ``` 82 | 83 | Actually these nodes are instances of `KKBasicContentItem`. It is a subclass of 84 | `MPContentItem`, and you can subclass `KKBasicContentItem` for your own need. 85 | 86 | ## Items/Nodes 87 | 88 | We added three methods on `KKBasicContentItem`: 89 | 90 | - `KKBasicContentItem.children`: A list of `KKBasicContentItem`. 91 | - `KKBasicContentItem.loadChildren(callback:)`: Ask the item to load its children. 92 | - `KKBasicContentItem.play(callback:)`: Play the item. 93 | 94 | There are two kinds of items/nodes, one is containers while another is playable 95 | items. 96 | 97 | ### Containers 98 | 99 | A container could be list a playlist or an album. It has it children. When you 100 | select a container on the CarPlay screen, 101 | `KKBasicContentItem.loadChildren(callback:)` would be called and the CarPlay 102 | screen goes to the next level and present its children items in a table UI. 103 | 104 | If you want to load children items from a file or from the Internet, subclass a 105 | KKBasicContentItem, set `isPlayable` to false and `isContainer` to true, do your 106 | loading in `KKBasicContentItem.loadChildren(callback:)` and remember to call the 107 | callback closure. 108 | 109 | KKCarPlayManager made a built-in container item type, `KKStaticContainerItem`. You 110 | can just use the class if you have a static list. 111 | 112 | ### Playable Items 113 | 114 | A playable item could be a song track, an audio book and so on. When a playable 115 | item is selected, the `KKBasicContentItem.play(callback:)` method would be 116 | called and your app should start playing. You should create your own subclasses 117 | for playable items in your app, since we are hardly to know how your player 118 | works and creates classes for you. 119 | 120 | If there is any error while playing, call the callback closure and pass the 121 | error, otherwise you can pass `nil`. 122 | 123 | ## A Full CarPlay Experience 124 | 125 | When you want to enable CarPlay in your audio app, 126 | 127 | - You need to have a valid provision profile/entitlement, otherwise your app 128 | won't appear on the CarPlay screen. Please contact Apple. 129 | - You need to enable some commands of [MPRemoteCommandCenter](https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter), otherwise 130 | `MPPlayableContentManager` won't call its data source and delegate. 131 | - Enable audio background mode and set the current category of [AVAudioSession](https://developer.apple.com/documentation/avfoundation/avaudiosession) 132 | to `.playback`, in order to enable background playabck. 133 | - Set up KKCarPlayManager as we mentioned above. 134 | - Once there are changes in your tree, call `MPPlayableContentManager.shared().beginUpdates()` and 135 | `MPPlayableContentManager.shared().endUpdates()`. 136 | - Provide now playing information to [MPNowPlayingInfoCenter](https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter). 137 | 138 | ## One More Thing 139 | 140 | On Xcode 11, you can use Swift UI like syntax to construct the node after 141 | importing `KKCarPlayManagerExtensions`. For example: 142 | 143 | ``` swift 144 | let rooNode = KKStaticContainerItem(identifier: "root", title: "Root") { 145 | KKStaticContainerItem(identifier: "folder1", title: "Folder 1") { 146 | PlayItem(identifier: "Song_1_1", title: "Song name", url: "song URL...") 147 | PlayItem(identifier: "Song_1_2", title: "Song name", url: "song URL...") 148 | } 149 | KKStaticContainerItem(identifier: "folder_2", title: "Folder 2") { 150 | PlayItem(identifier: "Song_2_1", title: "Song name", url: "song URL...") 151 | PlayItem(identifier: "Song_2_2", title: "Song name", url: "song URL...") 152 | } 153 | } 154 | ``` 155 | 156 | Enjoy! 🚗 157 | -------------------------------------------------------------------------------- /docs/Classes/KKStaticContainerItem.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKStaticContainerItem Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKStaticContainerItem

58 |
59 |
60 |
public class KKStaticContainerItem : KKBasicContentItem
61 | 62 |
63 |
64 |

A container item with static children.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | init(identifier:title:children:) 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    Creates an instance.

    84 | 85 |
    86 |
    87 |

    Declaration

    88 |
    89 |

    Swift

    90 |
    public init(identifier: String, title: String, children: [KKBasicContentItem])
    91 | 92 |
    93 |
    94 |
    95 |

    Parameters

    96 | 97 | 98 | 99 | 104 | 109 | 110 | 111 | 116 | 121 | 122 | 123 | 128 | 133 | 134 | 135 |
    100 | 101 | identifier 102 | 103 | 105 |
    106 |

    Identifier of the item.

    107 |
    108 |
    112 | 113 | title 114 | 115 | 117 |
    118 |

    Title of the item.

    119 |
    120 |
    124 | 125 | children 126 | 127 | 129 |
    130 |

    Children of the item.

    131 |
    132 |
    136 |
    137 |
    138 |
    139 |
  • 140 |
141 |
142 |
143 |
144 | 148 |
149 |
150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes/KKStaticContainerItem.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKStaticContainerItem Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKStaticContainerItem

58 |
59 |
60 |
public class KKStaticContainerItem : KKBasicContentItem
61 | 62 |
63 |
64 |

A container item with static children.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | init(identifier:title:children:) 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    Creates an instance.

    84 | 85 |
    86 |
    87 |

    Declaration

    88 |
    89 |

    Swift

    90 |
    public init(identifier: String, title: String, children: [KKBasicContentItem])
    91 | 92 |
    93 |
    94 |
    95 |

    Parameters

    96 | 97 | 98 | 99 | 104 | 109 | 110 | 111 | 116 | 121 | 122 | 123 | 128 | 133 | 134 | 135 |
    100 | 101 | identifier 102 | 103 | 105 |
    106 |

    Identifier of the item.

    107 |
    108 |
    112 | 113 | title 114 | 115 | 117 |
    118 |

    Title of the item.

    119 |
    120 |
    124 | 125 | children 126 | 127 | 129 |
    130 |

    Children of the item.

    131 |
    132 |
    136 |
    137 |
    138 |
    139 |
  • 140 |
141 |
142 |
143 |
144 | 148 |
149 |
150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/Classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Classes Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

Classes

58 |

The following classes are available globally.

59 | 60 |
61 |
62 |
63 |
    64 |
  • 65 |
    66 | 67 | 68 | 69 | KKBasicContentItem 70 | 71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 |

    KKBOX’s own subclass of MPContentItem.

    78 | 79 | See more 80 |
    81 |
    82 |

    Declaration

    83 |
    84 |

    Swift

    85 |
    open class KKBasicContentItem : MPContentItem
    86 | 87 |
    88 |
    89 |
    90 |
    91 |
  • 92 |
93 |
94 |
95 |
    96 |
  • 97 |
    98 | 99 | 100 | 101 | KKCarPlayManager 102 | 103 |
    104 |
    105 |
    106 |
    107 |
    108 |
    109 |

    A class helps your to build a tree structure of playable items for CarPlay.

    110 | 111 | See more 112 |
    113 |
    114 |

    Declaration

    115 |
    116 |

    Swift

    117 |
    public class KKCarPlayManager : NSObject
    118 | 119 |
    120 |
    121 |
    122 |
    123 |
  • 124 |
125 |
126 |
127 |
    128 |
  • 129 |
    130 | 131 | 132 | 133 | KKStaticContainerItem 134 | 135 |
    136 |
    137 |
    138 |
    139 |
    140 |
    141 |

    A container item with static children.

    142 | 143 | See more 144 |
    145 |
    146 |

    Declaration

    147 |
    148 |

    Swift

    149 |
    public class KKStaticContainerItem : KKBasicContentItem
    150 | 151 |
    152 |
    153 |
    154 |
    155 |
  • 156 |
157 |
158 |
159 |
160 | 164 |
165 |
166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Classes Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

Classes

58 |

The following classes are available globally.

59 | 60 |
61 |
62 |
63 |
    64 |
  • 65 |
    66 | 67 | 68 | 69 | KKBasicContentItem 70 | 71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 |

    KKBOX’s own subclass of MPContentItem.

    78 | 79 | See more 80 |
    81 |
    82 |

    Declaration

    83 |
    84 |

    Swift

    85 |
    open class KKBasicContentItem : MPContentItem
    86 | 87 |
    88 |
    89 |
    90 |
    91 |
  • 92 |
93 |
94 |
95 |
    96 |
  • 97 |
    98 | 99 | 100 | 101 | KKCarPlayManager 102 | 103 |
    104 |
    105 |
    106 |
    107 |
    108 |
    109 |

    A class helps your to build a tree structure of playable items for CarPlay.

    110 | 111 | See more 112 |
    113 |
    114 |

    Declaration

    115 |
    116 |

    Swift

    117 |
    public class KKCarPlayManager : NSObject
    118 | 119 |
    120 |
    121 |
    122 |
    123 |
  • 124 |
125 |
126 |
127 |
    128 |
  • 129 |
    130 | 131 | 132 | 133 | KKStaticContainerItem 134 | 135 |
    136 |
    137 |
    138 |
    139 |
    140 |
    141 |

    A container item with static children.

    142 | 143 | See more 144 |
    145 |
    146 |

    Declaration

    147 |
    148 |

    Swift

    149 |
    public class KKStaticContainerItem : KKBasicContentItem
    150 | 151 |
    152 |
    153 |
    154 |
    155 |
  • 156 |
157 |
158 |
159 |
160 | 164 |
165 |
166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | .main-content section .heading:before { 168 | content: ""; 169 | display: block; 170 | padding-top: 70px; 171 | margin: -70px 0 0; } 172 | 173 | .section { 174 | padding: 0 25px; } 175 | 176 | .highlight { 177 | background-color: #eee; 178 | padding: 10px 12px; 179 | border: 1px solid #e2e2e2; 180 | border-radius: 4px; 181 | overflow-x: auto; } 182 | 183 | .declaration .highlight { 184 | overflow-x: initial; 185 | padding: 0 40px 40px 0; 186 | margin-bottom: -25px; 187 | background-color: transparent; 188 | border: none; } 189 | 190 | .section-name { 191 | margin: 0; 192 | margin-left: 18px; } 193 | 194 | .task-group-section { 195 | padding-left: 6px; 196 | border-top: 1px solid #e2e2e2; } 197 | 198 | .task-group { 199 | padding-top: 0px; } 200 | 201 | .task-name-container a[name]:before { 202 | content: ""; 203 | display: block; 204 | padding-top: 70px; 205 | margin: -70px 0 0; } 206 | 207 | .item { 208 | padding-top: 8px; 209 | width: 100%; 210 | list-style-type: none; } 211 | .item a[name]:before { 212 | content: ""; 213 | display: block; 214 | padding-top: 70px; 215 | margin: -70px 0 0; } 216 | .item code { 217 | background-color: transparent; 218 | padding: 0; } 219 | .item .token { 220 | padding-left: 3px; 221 | margin-left: 15px; 222 | font-size: 11.9px; } 223 | .item .declaration-note { 224 | font-size: .85em; 225 | color: gray; 226 | font-style: italic; } 227 | 228 | .pointer-container { 229 | border-bottom: 1px solid #e2e2e2; 230 | left: -23px; 231 | padding-bottom: 13px; 232 | position: relative; 233 | width: 110%; } 234 | 235 | .pointer { 236 | background: #f9f9f9; 237 | border-left: 1px solid #e2e2e2; 238 | border-top: 1px solid #e2e2e2; 239 | height: 12px; 240 | left: 21px; 241 | top: -7px; 242 | -webkit-transform: rotate(45deg); 243 | -moz-transform: rotate(45deg); 244 | -o-transform: rotate(45deg); 245 | transform: rotate(45deg); 246 | position: absolute; 247 | width: 12px; } 248 | 249 | .height-container { 250 | display: none; 251 | left: -25px; 252 | padding: 0 25px; 253 | position: relative; 254 | width: 100%; 255 | overflow: hidden; } 256 | .height-container .section { 257 | background: #f9f9f9; 258 | border-bottom: 1px solid #e2e2e2; 259 | left: -25px; 260 | position: relative; 261 | width: 100%; 262 | padding-top: 10px; 263 | padding-bottom: 5px; } 264 | 265 | .aside, .language { 266 | padding: 6px 12px; 267 | margin: 12px 0; 268 | border-left: 5px solid #dddddd; 269 | overflow-y: hidden; } 270 | .aside .aside-title, .language .aside-title { 271 | font-size: 9px; 272 | letter-spacing: 2px; 273 | text-transform: uppercase; 274 | padding-bottom: 0; 275 | margin: 0; 276 | color: #aaa; 277 | -webkit-user-select: none; } 278 | .aside p:last-child, .language p:last-child { 279 | margin-bottom: 0; } 280 | 281 | .language { 282 | border-left: 5px solid #cde9f4; } 283 | .language .aside-title { 284 | color: #4b8afb; } 285 | 286 | .aside-warning { 287 | border-left: 5px solid #ff6666; } 288 | .aside-warning .aside-title { 289 | color: #ff0000; } 290 | 291 | .graybox { 292 | border-collapse: collapse; 293 | width: 100%; } 294 | .graybox p { 295 | margin: 0; 296 | word-break: break-word; 297 | min-width: 50px; } 298 | .graybox td { 299 | border: 1px solid #e2e2e2; 300 | padding: 5px 25px 5px 10px; 301 | vertical-align: middle; } 302 | .graybox tr td:first-of-type { 303 | text-align: right; 304 | padding: 7px; 305 | vertical-align: top; 306 | word-break: normal; 307 | width: 40px; } 308 | 309 | .slightly-smaller { 310 | font-size: 0.9em; } 311 | 312 | #footer { 313 | position: absolute; 314 | bottom: 10px; 315 | margin-left: 25px; } 316 | #footer p { 317 | margin: 0; 318 | color: #aaa; 319 | font-size: 0.8em; } 320 | 321 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 322 | display: none; } 323 | html.dash .main-content { 324 | width: 980px; 325 | margin-left: 0; 326 | border: none; 327 | width: 100%; 328 | top: 0; 329 | padding-bottom: 0; } 330 | html.dash .height-container { 331 | display: block; } 332 | html.dash .item .token { 333 | margin-left: 0; } 334 | html.dash .content-wrapper { 335 | width: auto; } 336 | html.dash #footer { 337 | position: static; } 338 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | .main-content section .heading:before { 168 | content: ""; 169 | display: block; 170 | padding-top: 70px; 171 | margin: -70px 0 0; } 172 | 173 | .section { 174 | padding: 0 25px; } 175 | 176 | .highlight { 177 | background-color: #eee; 178 | padding: 10px 12px; 179 | border: 1px solid #e2e2e2; 180 | border-radius: 4px; 181 | overflow-x: auto; } 182 | 183 | .declaration .highlight { 184 | overflow-x: initial; 185 | padding: 0 40px 40px 0; 186 | margin-bottom: -25px; 187 | background-color: transparent; 188 | border: none; } 189 | 190 | .section-name { 191 | margin: 0; 192 | margin-left: 18px; } 193 | 194 | .task-group-section { 195 | padding-left: 6px; 196 | border-top: 1px solid #e2e2e2; } 197 | 198 | .task-group { 199 | padding-top: 0px; } 200 | 201 | .task-name-container a[name]:before { 202 | content: ""; 203 | display: block; 204 | padding-top: 70px; 205 | margin: -70px 0 0; } 206 | 207 | .item { 208 | padding-top: 8px; 209 | width: 100%; 210 | list-style-type: none; } 211 | .item a[name]:before { 212 | content: ""; 213 | display: block; 214 | padding-top: 70px; 215 | margin: -70px 0 0; } 216 | .item code { 217 | background-color: transparent; 218 | padding: 0; } 219 | .item .token { 220 | padding-left: 3px; 221 | margin-left: 15px; 222 | font-size: 11.9px; } 223 | .item .declaration-note { 224 | font-size: .85em; 225 | color: gray; 226 | font-style: italic; } 227 | 228 | .pointer-container { 229 | border-bottom: 1px solid #e2e2e2; 230 | left: -23px; 231 | padding-bottom: 13px; 232 | position: relative; 233 | width: 110%; } 234 | 235 | .pointer { 236 | background: #f9f9f9; 237 | border-left: 1px solid #e2e2e2; 238 | border-top: 1px solid #e2e2e2; 239 | height: 12px; 240 | left: 21px; 241 | top: -7px; 242 | -webkit-transform: rotate(45deg); 243 | -moz-transform: rotate(45deg); 244 | -o-transform: rotate(45deg); 245 | transform: rotate(45deg); 246 | position: absolute; 247 | width: 12px; } 248 | 249 | .height-container { 250 | display: none; 251 | left: -25px; 252 | padding: 0 25px; 253 | position: relative; 254 | width: 100%; 255 | overflow: hidden; } 256 | .height-container .section { 257 | background: #f9f9f9; 258 | border-bottom: 1px solid #e2e2e2; 259 | left: -25px; 260 | position: relative; 261 | width: 100%; 262 | padding-top: 10px; 263 | padding-bottom: 5px; } 264 | 265 | .aside, .language { 266 | padding: 6px 12px; 267 | margin: 12px 0; 268 | border-left: 5px solid #dddddd; 269 | overflow-y: hidden; } 270 | .aside .aside-title, .language .aside-title { 271 | font-size: 9px; 272 | letter-spacing: 2px; 273 | text-transform: uppercase; 274 | padding-bottom: 0; 275 | margin: 0; 276 | color: #aaa; 277 | -webkit-user-select: none; } 278 | .aside p:last-child, .language p:last-child { 279 | margin-bottom: 0; } 280 | 281 | .language { 282 | border-left: 5px solid #cde9f4; } 283 | .language .aside-title { 284 | color: #4b8afb; } 285 | 286 | .aside-warning { 287 | border-left: 5px solid #ff6666; } 288 | .aside-warning .aside-title { 289 | color: #ff0000; } 290 | 291 | .graybox { 292 | border-collapse: collapse; 293 | width: 100%; } 294 | .graybox p { 295 | margin: 0; 296 | word-break: break-word; 297 | min-width: 50px; } 298 | .graybox td { 299 | border: 1px solid #e2e2e2; 300 | padding: 5px 25px 5px 10px; 301 | vertical-align: middle; } 302 | .graybox tr td:first-of-type { 303 | text-align: right; 304 | padding: 7px; 305 | vertical-align: top; 306 | word-break: normal; 307 | width: 40px; } 308 | 309 | .slightly-smaller { 310 | font-size: 0.9em; } 311 | 312 | #footer { 313 | position: absolute; 314 | bottom: 10px; 315 | margin-left: 25px; } 316 | #footer p { 317 | margin: 0; 318 | color: #aaa; 319 | font-size: 0.8em; } 320 | 321 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 322 | display: none; } 323 | html.dash .main-content { 324 | width: 980px; 325 | margin-left: 0; 326 | border: none; 327 | width: 100%; 328 | top: 0; 329 | padding-bottom: 0; } 330 | html.dash .height-container { 331 | display: block; } 332 | html.dash .item .token { 333 | margin-left: 0; } 334 | html.dash .content-wrapper { 335 | width: auto; } 336 | html.dash #footer { 337 | position: static; } 338 | -------------------------------------------------------------------------------- /docs/Classes/KKCarPlayManager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKCarPlayManager Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKCarPlayManager

58 |
59 |
60 |
public class KKCarPlayManager : NSObject
61 | 62 |
63 |
64 |

A class helps your to build a tree structure of playable items for CarPlay.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | activate() 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    Set the data source and delegate of MPPlayableContentManager to 84 | the current instance of KKCarPlayManager.

    85 | 86 |
    87 |
    88 |

    Declaration

    89 |
    90 |

    Swift

    91 |
    public func activate()
    92 | 93 |
    94 |
    95 |
    96 |
    97 |
  • 98 |
  • 99 |
    100 | 101 | 102 | 103 | deactivate() 104 | 105 |
    106 |
    107 |
    108 |
    109 |
    110 |
    111 |

    Set the data source and delegate of MPPlayableContentManager to nil.

    112 | 113 |
    114 |
    115 |

    Declaration

    116 |
    117 |

    Swift

    118 |
    public func deactivate()
    119 | 120 |
    121 |
    122 |
    123 |
    124 |
  • 125 |
  • 126 |
    127 | 128 | 129 | 130 | init(rootNode:) 131 | 132 |
    133 |
    134 |
    135 |
    136 |
    137 |
    138 |

    Creates a new instance.

    139 | 140 |
    141 |
    142 |

    Declaration

    143 |
    144 |

    Swift

    145 |
    public init(rootNode: KKBasicContentItem)
    146 | 147 |
    148 |
    149 |
    150 |

    Parameters

    151 | 152 | 153 | 154 | 159 | 164 | 165 | 166 |
    155 | 156 | rootNode 157 | 158 | 160 |
    161 |

    The root node.

    162 |
    163 |
    167 |
    168 |
    169 |
    170 |
  • 171 |
172 |
173 |
174 |
175 | 179 |
180 |
181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes/KKCarPlayManager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKCarPlayManager Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKCarPlayManager

58 |
59 |
60 |
public class KKCarPlayManager : NSObject
61 | 62 |
63 |
64 |

A class helps your to build a tree structure of playable items for CarPlay.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | activate() 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    Set the data source and delegate of MPPlayableContentManager to 84 | the current instance of KKCarPlayManager.

    85 | 86 |
    87 |
    88 |

    Declaration

    89 |
    90 |

    Swift

    91 |
    public func activate()
    92 | 93 |
    94 |
    95 |
    96 |
    97 |
  • 98 |
  • 99 |
    100 | 101 | 102 | 103 | deactivate() 104 | 105 |
    106 |
    107 |
    108 |
    109 |
    110 |
    111 |

    Set the data source and delegate of MPPlayableContentManager to nil.

    112 | 113 |
    114 |
    115 |

    Declaration

    116 |
    117 |

    Swift

    118 |
    public func deactivate()
    119 | 120 |
    121 |
    122 |
    123 |
    124 |
  • 125 |
  • 126 |
    127 | 128 | 129 | 130 | init(rootNode:) 131 | 132 |
    133 |
    134 |
    135 |
    136 |
    137 |
    138 |

    Creates a new instance.

    139 | 140 |
    141 |
    142 |

    Declaration

    143 |
    144 |

    Swift

    145 |
    public init(rootNode: KKBasicContentItem)
    146 | 147 |
    148 |
    149 |
    150 |

    Parameters

    151 | 152 | 153 | 154 | 159 | 164 | 165 | 166 |
    155 | 156 | rootNode 157 | 158 | 160 |
    161 |

    The root node.

    162 |
    163 |
    167 |
    168 |
    169 |
    170 |
  • 171 |
172 |
173 |
174 |
175 | 179 |
180 |
181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /docs/Classes/KKBasicContentItem.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKBasicContentItem Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKBasicContentItem

58 |
59 |
60 |
open class KKBasicContentItem : MPContentItem
61 | 62 |
63 |
64 |

KKBOX’s own subclass of MPContentItem.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | children 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    Childten items of the item. We use this property to build a tree and 84 | feed item on each index path to MPPlayableContentManager.

    85 | 86 |
    87 |
    88 |

    Declaration

    89 |
    90 |

    Swift

    91 |
    open var children: [KKBasicContentItem]?
    92 | 93 |
    94 |
    95 |
    96 |
    97 |
  • 98 |
  • 99 |
    100 | 101 | 102 | 103 | loadChildren(callback:) 104 | 105 |
    106 |
    107 |
    108 |
    109 |
    110 |
    111 |

    To load the children of the node.

    112 | 113 |
    114 |
    115 |

    Declaration

    116 |
    117 |

    Swift

    118 |
    open func loadChildren(callback: @escaping (Error?) -> Void) throws
    119 | 120 |
    121 |
    122 |
    123 |

    Parameters

    124 | 125 | 126 | 127 | 132 | 138 | 139 | 140 |
    128 | 129 | callback 130 | 131 | 133 |
    134 |

    the callback function. It contains an error object if it 135 | encounters any error while loading.

    136 |
    137 |
    141 |
    142 |
    143 |
    144 |
  • 145 |
  • 146 |
    147 | 148 | 149 | 150 | play(callback:) 151 | 152 |
    153 |
    154 |
    155 |
    156 |
    157 |
    158 |

    To play the media mapping to the item.

    159 | 160 |
    161 |
    162 |

    Declaration

    163 |
    164 |

    Swift

    165 |
    open func play(callback: @escaping (Error?) -> Void) throws -> Bool
    166 | 167 |
    168 |
    169 |
    170 |
    171 |
  • 172 |
173 |
174 |
175 |
    176 |
  • 177 |
    178 | 179 | 180 | 181 | apply(image:) 182 | 183 |
    184 |
    185 |
    186 |
    187 |
    188 |
    189 |

    Apply an image to the current item.

    190 | 191 |
    192 |
    193 |

    Declaration

    194 |
    195 |

    Swift

    196 |
    public func apply(image: UIImage?) -> KKBasicContentItem
    197 | 198 |
    199 |
    200 |
    201 |
    202 |
  • 203 |
204 |
205 |
206 |
207 | 211 |
212 |
213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes/KKBasicContentItem.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KKBasicContentItem Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

KKCarPlayManager Docs (100% documented)

18 |
19 |
20 |
21 | 26 |
27 |
28 | 54 |
55 |
56 |
57 |

KKBasicContentItem

58 |
59 |
60 |
open class KKBasicContentItem : MPContentItem
61 | 62 |
63 |
64 |

KKBOX’s own subclass of MPContentItem.

65 | 66 |
67 |
68 |
69 |
    70 |
  • 71 |
    72 | 73 | 74 | 75 | children 76 | 77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |

    Childten items of the item. We use this property to build a tree and 84 | feed item on each index path to MPPlayableContentManager.

    85 | 86 |
    87 |
    88 |

    Declaration

    89 |
    90 |

    Swift

    91 |
    open var children: [KKBasicContentItem]?
    92 | 93 |
    94 |
    95 |
    96 |
    97 |
  • 98 |
  • 99 |
    100 | 101 | 102 | 103 | loadChildren(callback:) 104 | 105 |
    106 |
    107 |
    108 |
    109 |
    110 |
    111 |

    To load the children of the node.

    112 | 113 |
    114 |
    115 |

    Declaration

    116 |
    117 |

    Swift

    118 |
    open func loadChildren(callback: @escaping (Error?) -> Void) throws
    119 | 120 |
    121 |
    122 |
    123 |

    Parameters

    124 | 125 | 126 | 127 | 132 | 138 | 139 | 140 |
    128 | 129 | callback 130 | 131 | 133 |
    134 |

    the callback function. It contains an error object if it 135 | encounters any error while loading.

    136 |
    137 |
    141 |
    142 |
    143 |
    144 |
  • 145 |
  • 146 |
    147 | 148 | 149 | 150 | play(callback:) 151 | 152 |
    153 |
    154 |
    155 |
    156 |
    157 |
    158 |

    To play the media mapping to the item.

    159 | 160 |
    161 |
    162 |

    Declaration

    163 |
    164 |

    Swift

    165 |
    open func play(callback: @escaping (Error?) -> Void) throws -> Bool
    166 | 167 |
    168 |
    169 |
    170 |
    171 |
  • 172 |
173 |
174 |
175 |
    176 |
  • 177 |
    178 | 179 | 180 | 181 | apply(image:) 182 | 183 |
    184 |
    185 |
    186 |
    187 |
    188 |
    189 |

    Apply an image to the current item.

    190 | 191 |
    192 |
    193 |

    Declaration

    194 |
    195 |

    Swift

    196 |
    public func apply(image: UIImage?) -> KKBasicContentItem
    197 | 198 |
    199 |
    200 |
    201 |
    202 |
  • 203 |
204 |
205 |
206 |
207 | 211 |
212 |
213 | 214 | 215 | 216 | --------------------------------------------------------------------------------