From bc08853e1f4816b5ec496d28f6772060990928e9 Mon Sep 17 00:00:00 2001 From: YuantongL Date: Tue, 29 Sep 2020 12:23:58 -0400 Subject: [PATCH 1/3] Support for macOS --- Examples/MacOS/Podfile | 19 + .../project.pbxproj | 409 ++++++++++ .../contents.xcworkspacedata | 3 - .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../AppDelegate.swift | 26 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 58 ++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/Main.storyboard | 717 ++++++++++++++++++ .../SpotlightLyricsMacExample/Info.plist | 30 + .../SpotlightLyricsMacExample.entitlements | 10 + .../ViewController.swift | 55 ++ .../SpotlightLyricsMacExample/imagine.lrc.txt | 43 ++ Examples/iOS/Podfile | 19 + .../project.pbxproj | 420 ++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../AppDelegate.swift | 36 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 +++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../Base.lproj/Main.storyboard | 24 + .../iOS/SpotlightLyricsIOSExample/Info.plist | 66 ++ .../SceneDelegate.swift | 52 ++ .../ViewController.swift | 50 ++ .../SpotlightLyricsIOSExample/imagine.lrc.txt | 43 ++ README.md | 6 +- README.zh-CN.md | 3 +- SpotlightLyrics.podspec | 16 +- SpotlightLyrics.xcodeproj/project.pbxproj | 365 --------- .../xcschemes/SpotlightLyrics.xcscheme | 80 -- .../xcschemes/xcschememanagement.plist | 22 - SpotlightLyrics/{ => Common}/Extensions.swift | 2 - .../LyricsParser/LyricsHeader.swift | 0 .../LyricsParser/LyricsItem.swift | 0 .../LyricsParser/LyricsParser.swift | 0 .../LyticsViewTimer.swift | 5 +- .../Mac/LyricsView/LyricsCell.swift | 76 ++ .../Mac/LyricsView/LyricsCellViewModel.swift | 85 +++ .../Mac/LyricsView/LyricsView.swift | 226 ++++++ .../{ => iOS}/LyricsView/LyricsCell.swift | 0 .../LyricsView/LyricsCellViewModel.swift | 4 +- .../{ => iOS}/LyricsView/LyricsView.swift | 1 - 48 files changed, 2692 insertions(+), 487 deletions(-) create mode 100644 Examples/MacOS/Podfile create mode 100644 Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.pbxproj rename {SpotlightLyrics.xcodeproj => Examples/MacOS/SpotlightLyricsMacExample.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (65%) rename {SpotlightLyrics.xcodeproj => Examples/MacOS/SpotlightLyricsMacExample.xcodeproj}/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) create mode 100644 Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/contents.xcworkspacedata create mode 100644 Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/AppDelegate.swift create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/Contents.json create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/Base.lproj/Main.storyboard create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/Info.plist create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/SpotlightLyricsMacExample.entitlements create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift create mode 100644 Examples/MacOS/SpotlightLyricsMacExample/imagine.lrc.txt create mode 100644 Examples/iOS/Podfile create mode 100644 Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.pbxproj create mode 100644 Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/contents.xcworkspacedata create mode 100644 Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/AppDelegate.swift create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/Contents.json create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/LaunchScreen.storyboard create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/Main.storyboard create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/Info.plist create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/SceneDelegate.swift create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift create mode 100644 Examples/iOS/SpotlightLyricsIOSExample/imagine.lrc.txt delete mode 100644 SpotlightLyrics.xcodeproj/project.pbxproj delete mode 100644 SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/SpotlightLyrics.xcscheme delete mode 100644 SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/xcschememanagement.plist rename SpotlightLyrics/{ => Common}/Extensions.swift (97%) rename SpotlightLyrics/{ => Common}/LyricsParser/LyricsHeader.swift (100%) rename SpotlightLyrics/{ => Common}/LyricsParser/LyricsItem.swift (100%) rename SpotlightLyrics/{ => Common}/LyricsParser/LyricsParser.swift (100%) rename SpotlightLyrics/{LyricsView => Common}/LyticsViewTimer.swift (95%) create mode 100644 SpotlightLyrics/Mac/LyricsView/LyricsCell.swift create mode 100644 SpotlightLyrics/Mac/LyricsView/LyricsCellViewModel.swift create mode 100644 SpotlightLyrics/Mac/LyricsView/LyricsView.swift rename SpotlightLyrics/{ => iOS}/LyricsView/LyricsCell.swift (100%) rename SpotlightLyrics/{ => iOS}/LyricsView/LyricsCellViewModel.swift (98%) rename SpotlightLyrics/{ => iOS}/LyricsView/LyricsView.swift (99%) diff --git a/Examples/MacOS/Podfile b/Examples/MacOS/Podfile new file mode 100644 index 0000000..246844f --- /dev/null +++ b/Examples/MacOS/Podfile @@ -0,0 +1,19 @@ +source 'https://github.com/CocoaPods/Specs.git' +source 'https://github.com/Artsy/Specs.git' + +platform :osx, '10.14' +inhibit_all_warnings! +use_frameworks! + +project 'SpotlightLyricsMacExample' + +target 'SpotlightLyricsMacExample' do + pod 'SpotlightLyrics', :path => '../../SpotlightLyrics.podspec' + pod 'SpotlightLyrics/Mac', :path => '../../SpotlightLyrics.podspec' +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + puts target.name + end +end diff --git a/Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.pbxproj b/Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0ad2968 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.pbxproj @@ -0,0 +1,409 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 448013E2252294C300835BB3 /* imagine.lrc.txt in Resources */ = {isa = PBXBuildFile; fileRef = 448013E1252294C300835BB3 /* imagine.lrc.txt */; }; + 44AA9E6B25226B3700C837C5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44AA9E6A25226B3700C837C5 /* AppDelegate.swift */; }; + 44AA9E6D25226B3700C837C5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44AA9E6C25226B3700C837C5 /* ViewController.swift */; }; + 44AA9E6F25226B3B00C837C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 44AA9E6E25226B3B00C837C5 /* Assets.xcassets */; }; + 44AA9E7225226B3B00C837C5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 44AA9E7025226B3B00C837C5 /* Main.storyboard */; }; + 9EF2DDE2FEF28BE6CE6F0D84 /* Pods_SpotlightLyricsMacExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC4DC3DD4DE1F7B674A621CE /* Pods_SpotlightLyricsMacExample.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2CFBC993979771D1D0A9BC1C /* Pods-SpotlightLyricsMacExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpotlightLyricsMacExample.debug.xcconfig"; path = "Target Support Files/Pods-SpotlightLyricsMacExample/Pods-SpotlightLyricsMacExample.debug.xcconfig"; sourceTree = ""; }; + 448013E1252294C300835BB3 /* imagine.lrc.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = imagine.lrc.txt; sourceTree = ""; }; + 44AA9E6725226B3700C837C5 /* SpotlightLyricsMacExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpotlightLyricsMacExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 44AA9E6A25226B3700C837C5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 44AA9E6C25226B3700C837C5 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 44AA9E6E25226B3B00C837C5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 44AA9E7125226B3B00C837C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 44AA9E7325226B3B00C837C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 44AA9E7425226B3B00C837C5 /* SpotlightLyricsMacExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SpotlightLyricsMacExample.entitlements; sourceTree = ""; }; + 4D15CE820CC98733C77E7566 /* Pods-SpotlightLyricsMacExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpotlightLyricsMacExample.release.xcconfig"; path = "Target Support Files/Pods-SpotlightLyricsMacExample/Pods-SpotlightLyricsMacExample.release.xcconfig"; sourceTree = ""; }; + FC4DC3DD4DE1F7B674A621CE /* Pods_SpotlightLyricsMacExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SpotlightLyricsMacExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 44AA9E6425226B3700C837C5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EF2DDE2FEF28BE6CE6F0D84 /* Pods_SpotlightLyricsMacExample.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 44AA9E5E25226B3700C837C5 = { + isa = PBXGroup; + children = ( + 44AA9E6925226B3700C837C5 /* SpotlightLyricsMacExample */, + 44AA9E6825226B3700C837C5 /* Products */, + 8A4167D2B6E3B5AE94789FB7 /* Pods */, + F25E80F3826493A0309FB5C5 /* Frameworks */, + ); + sourceTree = ""; + }; + 44AA9E6825226B3700C837C5 /* Products */ = { + isa = PBXGroup; + children = ( + 44AA9E6725226B3700C837C5 /* SpotlightLyricsMacExample.app */, + ); + name = Products; + sourceTree = ""; + }; + 44AA9E6925226B3700C837C5 /* SpotlightLyricsMacExample */ = { + isa = PBXGroup; + children = ( + 448013E1252294C300835BB3 /* imagine.lrc.txt */, + 44AA9E6A25226B3700C837C5 /* AppDelegate.swift */, + 44AA9E6C25226B3700C837C5 /* ViewController.swift */, + 44AA9E6E25226B3B00C837C5 /* Assets.xcassets */, + 44AA9E7025226B3B00C837C5 /* Main.storyboard */, + 44AA9E7325226B3B00C837C5 /* Info.plist */, + 44AA9E7425226B3B00C837C5 /* SpotlightLyricsMacExample.entitlements */, + ); + path = SpotlightLyricsMacExample; + sourceTree = ""; + }; + 8A4167D2B6E3B5AE94789FB7 /* Pods */ = { + isa = PBXGroup; + children = ( + 2CFBC993979771D1D0A9BC1C /* Pods-SpotlightLyricsMacExample.debug.xcconfig */, + 4D15CE820CC98733C77E7566 /* Pods-SpotlightLyricsMacExample.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + F25E80F3826493A0309FB5C5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + FC4DC3DD4DE1F7B674A621CE /* Pods_SpotlightLyricsMacExample.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 44AA9E6625226B3700C837C5 /* SpotlightLyricsMacExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 44AA9E7725226B3B00C837C5 /* Build configuration list for PBXNativeTarget "SpotlightLyricsMacExample" */; + buildPhases = ( + EAFAF53AF82A25DA5A4752B2 /* [CP] Check Pods Manifest.lock */, + 44AA9E6325226B3700C837C5 /* Sources */, + 44AA9E6425226B3700C837C5 /* Frameworks */, + 44AA9E6525226B3700C837C5 /* Resources */, + 8B964D355C10BC5EA39391C7 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SpotlightLyricsMacExample; + productName = SpotlightLyricsMacExample; + productReference = 44AA9E6725226B3700C837C5 /* SpotlightLyricsMacExample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 44AA9E5F25226B3700C837C5 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1200; + LastUpgradeCheck = 1200; + TargetAttributes = { + 44AA9E6625226B3700C837C5 = { + CreatedOnToolsVersion = 12.0; + }; + }; + }; + buildConfigurationList = 44AA9E6225226B3700C837C5 /* Build configuration list for PBXProject "SpotlightLyricsMacExample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 44AA9E5E25226B3700C837C5; + productRefGroup = 44AA9E6825226B3700C837C5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 44AA9E6625226B3700C837C5 /* SpotlightLyricsMacExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 44AA9E6525226B3700C837C5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 44AA9E6F25226B3B00C837C5 /* Assets.xcassets in Resources */, + 44AA9E7225226B3B00C837C5 /* Main.storyboard in Resources */, + 448013E2252294C300835BB3 /* imagine.lrc.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 8B964D355C10BC5EA39391C7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SpotlightLyricsMacExample/Pods-SpotlightLyricsMacExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SpotlightLyricsMacExample/Pods-SpotlightLyricsMacExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SpotlightLyricsMacExample/Pods-SpotlightLyricsMacExample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + EAFAF53AF82A25DA5A4752B2 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SpotlightLyricsMacExample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 44AA9E6325226B3700C837C5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 44AA9E6D25226B3700C837C5 /* ViewController.swift in Sources */, + 44AA9E6B25226B3700C837C5 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 44AA9E7025226B3B00C837C5 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 44AA9E7125226B3B00C837C5 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 44AA9E7525226B3B00C837C5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 44AA9E7625226B3B00C837C5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 44AA9E7825226B3B00C837C5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2CFBC993979771D1D0A9BC1C /* Pods-SpotlightLyricsMacExample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = SpotlightLyricsMacExample/SpotlightLyricsMacExample.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = XP69FP6Q2K; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = SpotlightLyricsMacExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = LYT.SpotlightLyricsMacExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 44AA9E7925226B3B00C837C5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4D15CE820CC98733C77E7566 /* Pods-SpotlightLyricsMacExample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = SpotlightLyricsMacExample/SpotlightLyricsMacExample.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = XP69FP6Q2K; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = SpotlightLyricsMacExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = LYT.SpotlightLyricsMacExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 44AA9E6225226B3700C837C5 /* Build configuration list for PBXProject "SpotlightLyricsMacExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 44AA9E7525226B3B00C837C5 /* Debug */, + 44AA9E7625226B3B00C837C5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 44AA9E7725226B3B00C837C5 /* Build configuration list for PBXNativeTarget "SpotlightLyricsMacExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 44AA9E7825226B3B00C837C5 /* Debug */, + 44AA9E7925226B3B00C837C5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 44AA9E5F25226B3700C837C5 /* Project object */; +} diff --git a/SpotlightLyrics.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 65% rename from SpotlightLyrics.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 65fd1eb..919434a 100644 --- a/SpotlightLyrics.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -1,9 +1,6 @@ - - diff --git a/SpotlightLyrics.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from SpotlightLyrics.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Examples/MacOS/SpotlightLyricsMacExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/contents.xcworkspacedata b/Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..30b56f2 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Examples/MacOS/SpotlightLyricsMacExample/AppDelegate.swift b/Examples/MacOS/SpotlightLyricsMacExample/AppDelegate.swift new file mode 100644 index 0000000..b1c08c2 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/AppDelegate.swift @@ -0,0 +1,26 @@ +// +// AppDelegate.swift +// SpotlightLyricsMacExample +// +// Created by Lyt on 9/28/20. +// + +import Cocoa + +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate { + + + + + func applicationDidFinishLaunching(_ aNotification: Notification) { + // Insert code here to initialize your application + } + + func applicationWillTerminate(_ aNotification: Notification) { + // Insert code here to tear down your application + } + + +} + diff --git a/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AccentColor.colorset/Contents.json b/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..3f00db4 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/Contents.json b/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/MacOS/SpotlightLyricsMacExample/Base.lproj/Main.storyboard b/Examples/MacOS/SpotlightLyricsMacExample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..09fd2f1 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/Base.lproj/Main.storyboard @@ -0,0 +1,717 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/MacOS/SpotlightLyricsMacExample/Info.plist b/Examples/MacOS/SpotlightLyricsMacExample/Info.plist new file mode 100644 index 0000000..cfbbdb7 --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSMainStoryboardFile + Main + NSPrincipalClass + NSApplication + + diff --git a/Examples/MacOS/SpotlightLyricsMacExample/SpotlightLyricsMacExample.entitlements b/Examples/MacOS/SpotlightLyricsMacExample/SpotlightLyricsMacExample.entitlements new file mode 100644 index 0000000..f2ef3ae --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/SpotlightLyricsMacExample.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + + diff --git a/Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift b/Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift new file mode 100644 index 0000000..a7c63dc --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift @@ -0,0 +1,55 @@ +// +// ViewController.swift +// SpotlightLyricsMacExample +// +// Created by Lyt on 9/28/20. +// + +import Cocoa +import SpotlightLyrics + +/// An example for usage of LyricsView +final class ViewController: NSViewController { + + private lazy var lyricsView: LyricsView = { + let lyricsView = LyricsView() + if let filepath = Bundle.main.path(forResource: "imagine.lrc", ofType: "txt") { + do { + let contents = try String(contentsOfFile: filepath) + lyricsView.lyrics = contents + } catch { + assertionFailure("contents could not be loaded") + } + } else { + assertionFailure("txt file not found") + } + return lyricsView + }() + + override func viewDidLoad() { + super.viewDidLoad() + setupLayout() + } + + override func viewDidAppear() { + super.viewDidAppear() + lyricsView.timer.play() + } + + private func setupLayout() { + NSLayoutConstraint.activate([ + view.heightAnchor.constraint(equalToConstant: 500) + ]) + + view.addSubview(lyricsView) + lyricsView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + lyricsView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + lyricsView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + lyricsView.topAnchor.constraint(equalTo: view.topAnchor), + lyricsView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } + +} + diff --git a/Examples/MacOS/SpotlightLyricsMacExample/imagine.lrc.txt b/Examples/MacOS/SpotlightLyricsMacExample/imagine.lrc.txt new file mode 100644 index 0000000..0095f4b --- /dev/null +++ b/Examples/MacOS/SpotlightLyricsMacExample/imagine.lrc.txt @@ -0,0 +1,43 @@ +[artist:Etta James] +[title:Imagine] +[album:All the Way] + +[00:00]Etta James - Imagine +[00:07](All the Way) +[00:13] +[00:15.48]Imagine there's no heaven +[00:22.67]It's easy if you try +[00:29.45]No hell below us +[00:36.42]Above us is only sky +[00:40.93] +[00:43.30]Imagine all the people +[00:48.80]Living for today +[00:55.36] +[00:57.18]Imagine there's no countries +[01:04.02]It isn't hard to do +[01:10.67]Nothing to kill or die for +[01:16.95]No religion too +[01:21.30] +[01:24.26]Imagine all the people +[01:29.92]Living life in peace, oh, yes +[01:37.63] +[01:37.64]You may say that I'm a dreamer +[01:44.05]But I'm not the only one +[01:50.76]I hope someday you'll join us +[01:56.88]And the world will live as one +[02:03.36] +[02:05.74]Imagine no possessions +[02:11.93]I wonder if you can +[02:18.67]No need for greed or hunger +[02:25.99]A brotherhood of man +[02:31.43] +[02:32.24]Imagine all the people +[02:38.43]Sharing all the world, oh oh oh +[02:46.03] +[02:46.26]You may say that I'm a dreamer +[02:52.51]But I'm not the only one +[02:59.26]I hope someday you'll join us +[03:05.49]And the world will live as one +[03:12.21]I hope someday you'll join us +[03:19.03]And the world will live as one +[03:31.02] diff --git a/Examples/iOS/Podfile b/Examples/iOS/Podfile new file mode 100644 index 0000000..a648227 --- /dev/null +++ b/Examples/iOS/Podfile @@ -0,0 +1,19 @@ +source 'https://github.com/CocoaPods/Specs.git' +source 'https://github.com/Artsy/Specs.git' + +platform :ios, '9.0' +inhibit_all_warnings! +use_frameworks! + +project 'SpotlightLyricsIOSExample' + +target 'SpotlightLyricsIOSExample' do + pod 'SpotlightLyrics', :path => '../../SpotlightLyrics.podspec' + pod 'SpotlightLyrics/iOS', :path => '../../SpotlightLyrics.podspec' +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + puts target.name + end +end diff --git a/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.pbxproj b/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..22bbffe --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.pbxproj @@ -0,0 +1,420 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 4480142E2522DF8900835BB3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480142D2522DF8900835BB3 /* AppDelegate.swift */; }; + 448014302522DF8900835BB3 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480142F2522DF8900835BB3 /* SceneDelegate.swift */; }; + 448014322522DF8900835BB3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448014312522DF8900835BB3 /* ViewController.swift */; }; + 448014352522DF8900835BB3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 448014332522DF8900835BB3 /* Main.storyboard */; }; + 448014372522DF8B00835BB3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 448014362522DF8B00835BB3 /* Assets.xcassets */; }; + 4480143A2522DF8B00835BB3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 448014382522DF8B00835BB3 /* LaunchScreen.storyboard */; }; + 44F2D9702523961C00FB6F7C /* imagine.lrc.txt in Resources */ = {isa = PBXBuildFile; fileRef = 44F2D96F2523961C00FB6F7C /* imagine.lrc.txt */; }; + 650D6CC821D473D9A06FD47F /* Pods_SpotlightLyricsIOSExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 042D56B34696BA1A684134ED /* Pods_SpotlightLyricsIOSExample.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 042D56B34696BA1A684134ED /* Pods_SpotlightLyricsIOSExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SpotlightLyricsIOSExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4480142A2522DF8900835BB3 /* SpotlightLyricsIOSExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpotlightLyricsIOSExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4480142D2522DF8900835BB3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 4480142F2522DF8900835BB3 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 448014312522DF8900835BB3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 448014342522DF8900835BB3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 448014362522DF8B00835BB3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 448014392522DF8B00835BB3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 4480143B2522DF8B00835BB3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 44F2D96F2523961C00FB6F7C /* imagine.lrc.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = imagine.lrc.txt; sourceTree = ""; }; + 75CC55E9AD3395A1F0469DBF /* Pods-SpotlightLyricsIOSExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpotlightLyricsIOSExample.release.xcconfig"; path = "Target Support Files/Pods-SpotlightLyricsIOSExample/Pods-SpotlightLyricsIOSExample.release.xcconfig"; sourceTree = ""; }; + E56EF7C7A9F23A1CA24B1D60 /* Pods-SpotlightLyricsIOSExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpotlightLyricsIOSExample.debug.xcconfig"; path = "Target Support Files/Pods-SpotlightLyricsIOSExample/Pods-SpotlightLyricsIOSExample.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 448014272522DF8900835BB3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 650D6CC821D473D9A06FD47F /* Pods_SpotlightLyricsIOSExample.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 05222A027D96751BA0B7B8E1 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 042D56B34696BA1A684134ED /* Pods_SpotlightLyricsIOSExample.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 448014212522DF8900835BB3 = { + isa = PBXGroup; + children = ( + 4480142C2522DF8900835BB3 /* SpotlightLyricsIOSExample */, + 4480142B2522DF8900835BB3 /* Products */, + 4D98A7E922E86C4215DF9381 /* Pods */, + 05222A027D96751BA0B7B8E1 /* Frameworks */, + ); + sourceTree = ""; + }; + 4480142B2522DF8900835BB3 /* Products */ = { + isa = PBXGroup; + children = ( + 4480142A2522DF8900835BB3 /* SpotlightLyricsIOSExample.app */, + ); + name = Products; + sourceTree = ""; + }; + 4480142C2522DF8900835BB3 /* SpotlightLyricsIOSExample */ = { + isa = PBXGroup; + children = ( + 4480142D2522DF8900835BB3 /* AppDelegate.swift */, + 4480142F2522DF8900835BB3 /* SceneDelegate.swift */, + 448014312522DF8900835BB3 /* ViewController.swift */, + 44F2D96F2523961C00FB6F7C /* imagine.lrc.txt */, + 448014332522DF8900835BB3 /* Main.storyboard */, + 448014362522DF8B00835BB3 /* Assets.xcassets */, + 448014382522DF8B00835BB3 /* LaunchScreen.storyboard */, + 4480143B2522DF8B00835BB3 /* Info.plist */, + ); + path = SpotlightLyricsIOSExample; + sourceTree = ""; + }; + 4D98A7E922E86C4215DF9381 /* Pods */ = { + isa = PBXGroup; + children = ( + E56EF7C7A9F23A1CA24B1D60 /* Pods-SpotlightLyricsIOSExample.debug.xcconfig */, + 75CC55E9AD3395A1F0469DBF /* Pods-SpotlightLyricsIOSExample.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 448014292522DF8900835BB3 /* SpotlightLyricsIOSExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4480143E2522DF8B00835BB3 /* Build configuration list for PBXNativeTarget "SpotlightLyricsIOSExample" */; + buildPhases = ( + 6235DB807C53705EFBCE103D /* [CP] Check Pods Manifest.lock */, + 448014262522DF8900835BB3 /* Sources */, + 448014272522DF8900835BB3 /* Frameworks */, + 448014282522DF8900835BB3 /* Resources */, + 80AB16B29019874E74A20E29 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SpotlightLyricsIOSExample; + productName = SpotlightLyricsIOSExample; + productReference = 4480142A2522DF8900835BB3 /* SpotlightLyricsIOSExample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 448014222522DF8900835BB3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1200; + LastUpgradeCheck = 1200; + TargetAttributes = { + 448014292522DF8900835BB3 = { + CreatedOnToolsVersion = 12.0.1; + }; + }; + }; + buildConfigurationList = 448014252522DF8900835BB3 /* Build configuration list for PBXProject "SpotlightLyricsIOSExample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 448014212522DF8900835BB3; + productRefGroup = 4480142B2522DF8900835BB3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 448014292522DF8900835BB3 /* SpotlightLyricsIOSExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 448014282522DF8900835BB3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4480143A2522DF8B00835BB3 /* LaunchScreen.storyboard in Resources */, + 448014372522DF8B00835BB3 /* Assets.xcassets in Resources */, + 44F2D9702523961C00FB6F7C /* imagine.lrc.txt in Resources */, + 448014352522DF8900835BB3 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 6235DB807C53705EFBCE103D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SpotlightLyricsIOSExample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 80AB16B29019874E74A20E29 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SpotlightLyricsIOSExample/Pods-SpotlightLyricsIOSExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SpotlightLyricsIOSExample/Pods-SpotlightLyricsIOSExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SpotlightLyricsIOSExample/Pods-SpotlightLyricsIOSExample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 448014262522DF8900835BB3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 448014322522DF8900835BB3 /* ViewController.swift in Sources */, + 4480142E2522DF8900835BB3 /* AppDelegate.swift in Sources */, + 448014302522DF8900835BB3 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 448014332522DF8900835BB3 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 448014342522DF8900835BB3 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 448014382522DF8B00835BB3 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 448014392522DF8B00835BB3 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 4480143C2522DF8B00835BB3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 4480143D2522DF8B00835BB3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 4480143F2522DF8B00835BB3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E56EF7C7A9F23A1CA24B1D60 /* Pods-SpotlightLyricsIOSExample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XP69FP6Q2K; + INFOPLIST_FILE = SpotlightLyricsIOSExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = LYT.SpotlightLyricsIOSExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 448014402522DF8B00835BB3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75CC55E9AD3395A1F0469DBF /* Pods-SpotlightLyricsIOSExample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XP69FP6Q2K; + INFOPLIST_FILE = SpotlightLyricsIOSExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = LYT.SpotlightLyricsIOSExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 448014252522DF8900835BB3 /* Build configuration list for PBXProject "SpotlightLyricsIOSExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4480143C2522DF8B00835BB3 /* Debug */, + 4480143D2522DF8B00835BB3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4480143E2522DF8B00835BB3 /* Build configuration list for PBXNativeTarget "SpotlightLyricsIOSExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4480143F2522DF8B00835BB3 /* Debug */, + 448014402522DF8B00835BB3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 448014222522DF8900835BB3 /* Project object */; +} diff --git a/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/contents.xcworkspacedata b/Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..be6fc6f --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Examples/iOS/SpotlightLyricsIOSExample/AppDelegate.swift b/Examples/iOS/SpotlightLyricsIOSExample/AppDelegate.swift new file mode 100644 index 0000000..a03a696 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// SpotlightLyricsIOSExample +// +// Created by Lyt on 9/28/20. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AccentColor.colorset/Contents.json b/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/Contents.json b/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/LaunchScreen.storyboard b/Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/Main.storyboard b/Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..25a7638 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/iOS/SpotlightLyricsIOSExample/Info.plist b/Examples/iOS/SpotlightLyricsIOSExample/Info.plist new file mode 100644 index 0000000..5b531f7 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/Info.plist @@ -0,0 +1,66 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Examples/iOS/SpotlightLyricsIOSExample/SceneDelegate.swift b/Examples/iOS/SpotlightLyricsIOSExample/SceneDelegate.swift new file mode 100644 index 0000000..c183c5a --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// SpotlightLyricsIOSExample +// +// Created by Lyt on 9/28/20. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift b/Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift new file mode 100644 index 0000000..2b12e90 --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift @@ -0,0 +1,50 @@ +// +// ViewController.swift +// SpotlightLyricsIOSExample +// +// Created by Lyt on 9/28/20. +// + +import UIKit +import SpotlightLyrics + +class ViewController: UIViewController { + + private lazy var lyricsView: LyricsView = { + let lyricsView = LyricsView() + if let filepath = Bundle.main.path(forResource: "imagine.lrc", ofType: "txt") { + do { + let contents = try String(contentsOfFile: filepath) + lyricsView.lyrics = contents + } catch { + assertionFailure("contents could not be loaded") + } + } else { + assertionFailure("txt file not found") + } + return lyricsView + }() + + override func viewDidLoad() { + super.viewDidLoad() + setupLayout() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + lyricsView.timer.play() + } + + private func setupLayout() { + view.addSubview(lyricsView) + lyricsView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + lyricsView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + lyricsView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + lyricsView.topAnchor.constraint(equalTo: view.topAnchor), + lyricsView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } + +} + diff --git a/Examples/iOS/SpotlightLyricsIOSExample/imagine.lrc.txt b/Examples/iOS/SpotlightLyricsIOSExample/imagine.lrc.txt new file mode 100644 index 0000000..0095f4b --- /dev/null +++ b/Examples/iOS/SpotlightLyricsIOSExample/imagine.lrc.txt @@ -0,0 +1,43 @@ +[artist:Etta James] +[title:Imagine] +[album:All the Way] + +[00:00]Etta James - Imagine +[00:07](All the Way) +[00:13] +[00:15.48]Imagine there's no heaven +[00:22.67]It's easy if you try +[00:29.45]No hell below us +[00:36.42]Above us is only sky +[00:40.93] +[00:43.30]Imagine all the people +[00:48.80]Living for today +[00:55.36] +[00:57.18]Imagine there's no countries +[01:04.02]It isn't hard to do +[01:10.67]Nothing to kill or die for +[01:16.95]No religion too +[01:21.30] +[01:24.26]Imagine all the people +[01:29.92]Living life in peace, oh, yes +[01:37.63] +[01:37.64]You may say that I'm a dreamer +[01:44.05]But I'm not the only one +[01:50.76]I hope someday you'll join us +[01:56.88]And the world will live as one +[02:03.36] +[02:05.74]Imagine no possessions +[02:11.93]I wonder if you can +[02:18.67]No need for greed or hunger +[02:25.99]A brotherhood of man +[02:31.43] +[02:32.24]Imagine all the people +[02:38.43]Sharing all the world, oh oh oh +[02:46.03] +[02:46.26]You may say that I'm a dreamer +[02:52.51]But I'm not the only one +[02:59.26]I hope someday you'll join us +[03:05.49]And the world will live as one +[03:12.21]I hope someday you'll join us +[03:19.03]And the world will live as one +[03:31.02] diff --git a/README.md b/README.md index 7911962..53104b9 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## Introducing -`SpotlightLyrics` is an open-source library which helps developers in parsing & displaying [LRC files](), it is completely developed under [Swift](https://github.com/Apple/Swift) 4.2 and designed for both iPhone and iPad platforms. +`SpotlightLyrics` is an open-source library which helps developers in parsing & displaying [LRC files](), it is completely developed under [Swift](https://github.com/Apple/Swift) 4.2 and designed for iOS and macOS.
@@ -25,11 +25,13 @@ pod 'SpotlightLyrics' ``` +Use `pod 'SpotlightLyrics/Mac'` or `pod 'SpotlightLyrics/Mac'` to only pull in the subspec for a specific platform. + ### Manually - Download or clone the repository and then compile it to obtain `SpotlightLyrics.framework`, - Copy `SpotlightLyrics.framework` from frameworks folder to the your project, -- Open your project in XCode and navigate to `General` - `Linked Frameworks and Libraries` to add the component into you project +- Open your project in Xcode and navigate to `General` - `Linked Frameworks and Libraries` to add the component into you project ## How To Use diff --git a/README.zh-CN.md b/README.zh-CN.md index 959e212..e79bdad 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -8,7 +8,7 @@ For English descriptions, click [here](README.md) ## 介绍 -`SpotlightLyrics`是一个开源库,主要用来解析并显示[LRC 歌词文件](),它完全使用[Swift](https://github.com/Apple/Swift)来开发并为 iPhone 和 iPad 平台而设计。 +`SpotlightLyrics`是一个开源库,主要用来解析并显示[LRC 歌词文件](),它完全使用[Swift](https://github.com/Apple/Swift)来开发并支持iOS和macOS。
@@ -24,6 +24,7 @@ For English descriptions, click [here](README.md) ``` pod 'SpotlightLyrics' ``` +也可用`pod 'SpotlightLyrics/Mac'` 或 `pod 'SpotlightLyrics/Mac'`来只导入所需的平台代码。 ### 手动集成 diff --git a/SpotlightLyrics.podspec b/SpotlightLyrics.podspec index 98f35a1..07716df 100644 --- a/SpotlightLyrics.podspec +++ b/SpotlightLyrics.podspec @@ -2,16 +2,24 @@ Pod::Spec.new do |s| s.name = 'SpotlightLyrics' s.version = '0.1.5' s.license = 'MIT' - s.summary = 'An LRC file parser for iOS.' + s.summary = 'An LRC file parser for iOS and MacOS.' s.homepage = 'https://github.com/jayasme/SpotlightLyrics' # s.social_media_url = '' s.authors = { 'jayasme' => 'sunshine121981@126.com' } s.source = { :git => "https://github.com/jayasme/SpotlightLyrics.git", :tag => s.version } # s.documentation_url = '' - s.ios.deployment_target = '8.0' - s.swift_version = "4.2" - s.source_files = 'SpotlightLyrics/**/*.swift' + s.source_files = 'SpotlightLyrics/Common/**/*.swift' + + s.subspec 'iOS' do |i| + i.ios.deployment_target = "8.0" + i.source_files = 'SpotlightLyrics/iOS/**/*.swift' + end + + s.subspec 'Mac' do |m| + m.osx.deployment_target = "10.12" + m.source_files = 'SpotlightLyrics/Mac/**/*.swift' + end end diff --git a/SpotlightLyrics.xcodeproj/project.pbxproj b/SpotlightLyrics.xcodeproj/project.pbxproj deleted file mode 100644 index f743dd1..0000000 --- a/SpotlightLyrics.xcodeproj/project.pbxproj +++ /dev/null @@ -1,365 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1D079FD621B6608F00D21A8F /* LyricsParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D079FCC21B6608F00D21A8F /* LyricsParser.swift */; }; - 1D079FD721B6608F00D21A8F /* LyricsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D079FCD21B6608F00D21A8F /* LyricsItem.swift */; }; - 1D079FD821B6608F00D21A8F /* LyricsHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D079FCE21B6608F00D21A8F /* LyricsHeader.swift */; }; - 1D079FD921B6608F00D21A8F /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D079FCF21B6608F00D21A8F /* Extensions.swift */; }; - 1D079FDA21B6608F00D21A8F /* LyricsCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D079FD121B6608F00D21A8F /* LyricsCellViewModel.swift */; }; - 1D079FDB21B6608F00D21A8F /* LyricsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D079FD221B6608F00D21A8F /* LyricsView.swift */; }; - 1D079FDC21B6608F00D21A8F /* LyricsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D079FD321B6608F00D21A8F /* LyricsCell.swift */; }; - 1D3C8B1221BA7BB10020933A /* LyticsViewTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3C8B1121BA7BB10020933A /* LyticsViewTimer.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 1D079FCA21B6608F00D21A8F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 1D079FCC21B6608F00D21A8F /* LyricsParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LyricsParser.swift; sourceTree = ""; }; - 1D079FCD21B6608F00D21A8F /* LyricsItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LyricsItem.swift; sourceTree = ""; }; - 1D079FCE21B6608F00D21A8F /* LyricsHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LyricsHeader.swift; sourceTree = ""; }; - 1D079FCF21B6608F00D21A8F /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; - 1D079FD121B6608F00D21A8F /* LyricsCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LyricsCellViewModel.swift; sourceTree = ""; }; - 1D079FD221B6608F00D21A8F /* LyricsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LyricsView.swift; sourceTree = ""; }; - 1D079FD321B6608F00D21A8F /* LyricsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LyricsCell.swift; sourceTree = ""; }; - 1D3C8B1121BA7BB10020933A /* LyticsViewTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LyticsViewTimer.swift; sourceTree = ""; }; - 1DEA77031F259A6C00C1040B /* SpotlightLyrics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SpotlightLyrics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1DEA76FF1F259A6C00C1040B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1D079FC121B6603D00D21A8F /* SpotlightLyrics */ = { - isa = PBXGroup; - children = ( - 1D079FCB21B6608F00D21A8F /* LyricsParser */, - 1D079FD021B6608F00D21A8F /* LyricsView */, - 1D079FCF21B6608F00D21A8F /* Extensions.swift */, - 1D079FCA21B6608F00D21A8F /* Info.plist */, - ); - path = SpotlightLyrics; - sourceTree = ""; - }; - 1D079FCB21B6608F00D21A8F /* LyricsParser */ = { - isa = PBXGroup; - children = ( - 1D079FCC21B6608F00D21A8F /* LyricsParser.swift */, - 1D079FCD21B6608F00D21A8F /* LyricsItem.swift */, - 1D079FCE21B6608F00D21A8F /* LyricsHeader.swift */, - ); - path = LyricsParser; - sourceTree = ""; - }; - 1D079FD021B6608F00D21A8F /* LyricsView */ = { - isa = PBXGroup; - children = ( - 1D079FD221B6608F00D21A8F /* LyricsView.swift */, - 1D3C8B1121BA7BB10020933A /* LyticsViewTimer.swift */, - 1D079FD121B6608F00D21A8F /* LyricsCellViewModel.swift */, - 1D079FD321B6608F00D21A8F /* LyricsCell.swift */, - ); - path = LyricsView; - sourceTree = ""; - }; - 1DEA76F91F259A6C00C1040B = { - isa = PBXGroup; - children = ( - 1D079FC121B6603D00D21A8F /* SpotlightLyrics */, - 1DEA77041F259A6C00C1040B /* Products */, - ); - sourceTree = ""; - }; - 1DEA77041F259A6C00C1040B /* Products */ = { - isa = PBXGroup; - children = ( - 1DEA77031F259A6C00C1040B /* SpotlightLyrics.framework */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 1DEA77001F259A6C00C1040B /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 1DEA77021F259A6C00C1040B /* SpotlightLyrics */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEA770B1F259A6C00C1040B /* Build configuration list for PBXNativeTarget "SpotlightLyrics" */; - buildPhases = ( - 1DEA76FE1F259A6C00C1040B /* Sources */, - 1DEA76FF1F259A6C00C1040B /* Frameworks */, - 1DEA77001F259A6C00C1040B /* Headers */, - 1DEA77011F259A6C00C1040B /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = SpotlightLyrics; - productName = SpotlightLyrics; - productReference = 1DEA77031F259A6C00C1040B /* SpotlightLyrics.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 1DEA76FA1F259A6C00C1040B /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1010; - ORGANIZATIONNAME = "Scott Rong"; - TargetAttributes = { - 1DEA77021F259A6C00C1040B = { - CreatedOnToolsVersion = 8.3.3; - LastSwiftMigration = 1010; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 1DEA76FD1F259A6C00C1040B /* Build configuration list for PBXProject "SpotlightLyrics" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 1DEA76F91F259A6C00C1040B; - productRefGroup = 1DEA77041F259A6C00C1040B /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 1DEA77021F259A6C00C1040B /* SpotlightLyrics */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 1DEA77011F259A6C00C1040B /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 1DEA76FE1F259A6C00C1040B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1D079FD721B6608F00D21A8F /* LyricsItem.swift in Sources */, - 1D079FD821B6608F00D21A8F /* LyricsHeader.swift in Sources */, - 1D079FDA21B6608F00D21A8F /* LyricsCellViewModel.swift in Sources */, - 1D079FD621B6608F00D21A8F /* LyricsParser.swift in Sources */, - 1D079FDB21B6608F00D21A8F /* LyricsView.swift in Sources */, - 1D079FDC21B6608F00D21A8F /* LyricsCell.swift in Sources */, - 1D3C8B1221BA7BB10020933A /* LyticsViewTimer.swift in Sources */, - 1D079FD921B6608F00D21A8F /* Extensions.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEA77091F259A6C00C1040B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 1DEA770A1F259A6C00C1040B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 1DEA770C1F259A6C00C1040B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "$(SRCROOT)/SpotlightLyrics/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.jayasme.spotlight-lyrics"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; - }; - name = Debug; - }; - 1DEA770D1F259A6C00C1040B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "$(SRCROOT)/SpotlightLyrics/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.jayasme.spotlight-lyrics"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEA76FD1F259A6C00C1040B /* Build configuration list for PBXProject "SpotlightLyrics" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEA77091F259A6C00C1040B /* Debug */, - 1DEA770A1F259A6C00C1040B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEA770B1F259A6C00C1040B /* Build configuration list for PBXNativeTarget "SpotlightLyrics" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEA770C1F259A6C00C1040B /* Debug */, - 1DEA770D1F259A6C00C1040B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 1DEA76FA1F259A6C00C1040B /* Project object */; -} diff --git a/SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/SpotlightLyrics.xcscheme b/SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/SpotlightLyrics.xcscheme deleted file mode 100644 index b186391..0000000 --- a/SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/SpotlightLyrics.xcscheme +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/xcschememanagement.plist b/SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index bb5c0e7..0000000 --- a/SpotlightLyrics.xcodeproj/xcuserdata/ScottRong.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - SpotlightLyrics.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - 1DEA77021F259A6C00C1040B - - primary - - - - - diff --git a/SpotlightLyrics/Extensions.swift b/SpotlightLyrics/Common/Extensions.swift similarity index 97% rename from SpotlightLyrics/Extensions.swift rename to SpotlightLyrics/Common/Extensions.swift index f912a42..a235f43 100644 --- a/SpotlightLyrics/Extensions.swift +++ b/SpotlightLyrics/Common/Extensions.swift @@ -6,8 +6,6 @@ // Copyright © 2017 Scott Rong. All rights reserved. // -import UIKit - extension CharacterSet { public static var quotes = CharacterSet(charactersIn: "\"'") } diff --git a/SpotlightLyrics/LyricsParser/LyricsHeader.swift b/SpotlightLyrics/Common/LyricsParser/LyricsHeader.swift similarity index 100% rename from SpotlightLyrics/LyricsParser/LyricsHeader.swift rename to SpotlightLyrics/Common/LyricsParser/LyricsHeader.swift diff --git a/SpotlightLyrics/LyricsParser/LyricsItem.swift b/SpotlightLyrics/Common/LyricsParser/LyricsItem.swift similarity index 100% rename from SpotlightLyrics/LyricsParser/LyricsItem.swift rename to SpotlightLyrics/Common/LyricsParser/LyricsItem.swift diff --git a/SpotlightLyrics/LyricsParser/LyricsParser.swift b/SpotlightLyrics/Common/LyricsParser/LyricsParser.swift similarity index 100% rename from SpotlightLyrics/LyricsParser/LyricsParser.swift rename to SpotlightLyrics/Common/LyricsParser/LyricsParser.swift diff --git a/SpotlightLyrics/LyricsView/LyticsViewTimer.swift b/SpotlightLyrics/Common/LyticsViewTimer.swift similarity index 95% rename from SpotlightLyrics/LyricsView/LyticsViewTimer.swift rename to SpotlightLyrics/Common/LyticsViewTimer.swift index 7a176f3..aa6796e 100644 --- a/SpotlightLyrics/LyricsView/LyticsViewTimer.swift +++ b/SpotlightLyrics/Common/LyticsViewTimer.swift @@ -6,10 +6,7 @@ // Copyright © 2018 Scott Rong. All rights reserved. // -import UIKit - - -public class LyricsViewTimer { +public final class LyricsViewTimer { private let TICK_INTERVAL: TimeInterval = 0.1 diff --git a/SpotlightLyrics/Mac/LyricsView/LyricsCell.swift b/SpotlightLyrics/Mac/LyricsView/LyricsCell.swift new file mode 100644 index 0000000..f5b29ee --- /dev/null +++ b/SpotlightLyrics/Mac/LyricsView/LyricsCell.swift @@ -0,0 +1,76 @@ +// +// LyricsCell.swift +// SpotlightLyrics +// +// Created by Lyt on 9/28/20. +// + +import Foundation + +open class LyricsCell: NSView { + + private var lyricLabel: NSTextField = { + let textField = NSTextField(labelWithString: "") + textField.isEditable = false + textField.alignment = .center + textField.maximumNumberOfLines = 0 + return textField + }() + + init() { + isHighlighted = false + super.init(frame: .zero) + setupLayout() + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupLayout() { + translatesAutoresizingMaskIntoConstraints = false + + addSubview(lyricLabel) + lyricLabel.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + lyricLabel.centerYAnchor.constraint(equalTo: centerYAnchor), + lyricLabel.leadingAnchor.constraint(equalTo: leadingAnchor), + lyricLabel.trailingAnchor.constraint(equalTo: trailingAnchor), + lyricLabel.topAnchor.constraint(greaterThanOrEqualTo: topAnchor), + lyricLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor) + ]) + } + + public var isHighlighted: Bool { + didSet { + applyViewModel() + } + } + + func update(with viewModel: LyricsCellViewModel) { + self.viewModel = viewModel + applyViewModel() + } + + private func applyViewModel() { + guard let viewModel = self.viewModel else { + return + } + + if isHighlighted { + lyricLabel.font = viewModel.highlightedFont + lyricLabel.textColor = viewModel.highlightedTextColor + } else { + lyricLabel.font = viewModel.font + lyricLabel.textColor = viewModel.textColor + } + //lyricLabel.attributedStringValue = (isHighlighted ? viewModel.highlightedAttributedString : viewModel.attributedString) ?? NSAttributedString(string: "") + lyricLabel.stringValue = viewModel.lyric + + lyricLabel.sizeThatFits(CGSize(width: bounds.width, height: bounds.height)) + + viewModel.cell = self + } + + private weak var viewModel : LyricsCellViewModel? = nil +} diff --git a/SpotlightLyrics/Mac/LyricsView/LyricsCellViewModel.swift b/SpotlightLyrics/Mac/LyricsView/LyricsCellViewModel.swift new file mode 100644 index 0000000..ea9a694 --- /dev/null +++ b/SpotlightLyrics/Mac/LyricsView/LyricsCellViewModel.swift @@ -0,0 +1,85 @@ +// +// LyricsCellViewModel.swift +// SpotlightLyrics +// +// Created by Lyt on 9/28/20. +// + +internal final class LyricsCellViewModel { + + // MARK: Properties + + public var lyric: String { + didSet { + update() + } + } + + public var font: NSFont { + didSet { + update() + } + } + + public var highlightedFont: NSFont { + didSet { + update() + } + } + + public var textColor: NSColor { + didSet { + update() + } + } + + public var highlightedTextColor: NSColor { + didSet { + update() + } + } + + public var highlighted: Bool = false { + didSet { + cell?.isHighlighted = highlighted + } + } + + public static func cellViewModel(lyric: String, font: NSFont, highlightedFont: NSFont, textColor: NSColor, highlightedTextColor: NSColor) -> LyricsCellViewModel { + return LyricsCellViewModel(lyric: lyric, + font: font, + highlightedFont: highlightedFont, + textColor: textColor, + highlightedTextColor: highlightedTextColor) + } + + fileprivate init(lyric: String, font: NSFont, highlightedFont: NSFont, textColor: NSColor, highlightedTextColor: NSColor) { + self.lyric = lyric + self.font = font + self.highlightedFont = highlightedFont + self.textColor = textColor + self.highlightedTextColor = highlightedTextColor + update() + } + + private func update() { + // produce the attributedString + attributedString = NSAttributedString(string: lyric, attributes: [.font: font]) + highlightedAttributedString = NSAttributedString(string: lyric, attributes: [.font: highlightedFont]) + cell?.update(with: self) + } + + public var attributedString: NSAttributedString? = nil + public var highlightedAttributedString: NSAttributedString? = nil + + public func calcHeight(containerWidth: CGFloat) -> CGFloat { + let boundingSize = CGSize(width: containerWidth, height: 9999) + if highlighted { + return highlightedAttributedString?.boundingRect(with: boundingSize, options: .usesLineFragmentOrigin, context: nil).height ?? 0 + } else { + return attributedString?.boundingRect(with: boundingSize, options: .usesLineFragmentOrigin, context: nil).height ?? 0 + } + } + + internal weak var cell: LyricsCell? = nil +} diff --git a/SpotlightLyrics/Mac/LyricsView/LyricsView.swift b/SpotlightLyrics/Mac/LyricsView/LyricsView.swift new file mode 100644 index 0000000..bbc8f3a --- /dev/null +++ b/SpotlightLyrics/Mac/LyricsView/LyricsView.swift @@ -0,0 +1,226 @@ +// +// LyricsView.swift +// SpotlightLyrics +// +// Created by Lyt on 9/28/20. +// + +open class LyricsView: NSView { + + private let cellIdentifier: NSUserInterfaceItemIdentifier = .init(rawValue: "LyricsCell") + + private var parser: LyricsParser? = nil + + private var lyricsViewModels: [LyricsCellViewModel] = [] + + private var lastIndex: Int? = nil + + private(set) public var timer: LyricsViewTimer = LyricsViewTimer() + + private var scrollViewHadScrolledByUser = false + + private let scrollView: NSScrollView = { + let scrollView = NSScrollView() + scrollView.drawsBackground = false + scrollView.backgroundColor = .clear + return scrollView + }() + + private lazy var tableView: NSTableView = { + let tableView = NSTableView() + tableView.dataSource = self + tableView.delegate = self + tableView.selectionHighlightStyle = .none + tableView.headerView = nil + tableView.gridColor = .clear + tableView.wantsLayer = true + tableView.backgroundColor = .clear + return tableView + }() + + // MARK: Public properties + + public var currentLyric: String? { + get { + guard let lastIndex = lastIndex else { + return nil + } + guard lastIndex < lyricsViewModels.count else { + return nil + } + + return lyricsViewModels[lastIndex].lyric + } + } + + public var lyrics: String? = nil { + didSet { + reloadViewModels() + } + } + + public var lyricFont: NSFont = .systemFont(ofSize: 14) { + didSet { + reloadViewModels() + } + } + + public var lyricHighlightedFont: NSFont = .systemFont(ofSize: 24) { + didSet { + reloadViewModels() + } + } + + public var lyricTextColor: NSColor = .labelColor { + didSet { + reloadViewModels() + } + } + + public var lyricHighlightedTextColor: NSColor = .selectedTextColor { + didSet { + reloadViewModels() + } + } + + public var lineSpacing: CGFloat = 16 { + didSet { + reloadViewModels() + } + } + + // MARK: Initializations + + override init(frame: CGRect) { + super.init(frame: frame) + setupLayout() + setupBinding() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + private func setupBinding() { + scrollView.postsFrameChangedNotifications = true + NotificationCenter.default.addObserver(self, + selector: #selector(scrollViewDidEndLiveScroll(notification:)), + name: NSScrollView.willStartLiveScrollNotification, + object: scrollView) + } + + private func setupLayout() { + timer.lyricsView = self + + addSubview(scrollView) + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.documentView = tableView + NSLayoutConstraint.activate([ + scrollView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8), + scrollView.topAnchor.constraint(equalTo: topAnchor, constant: 8), + scrollView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8), + scrollView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8), + scrollView.widthAnchor.constraint(greaterThanOrEqualToConstant: 400) + ]) + + let column = NSTableColumn(identifier: cellIdentifier) + column.minWidth = 400 + tableView.addTableColumn(column) + } +} + +extension LyricsView: NSTableViewDataSource { + public func numberOfRows(in tableView: NSTableView) -> Int { + lyricsViewModels.count + } + + public func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { + let cellViewModel = lyricsViewModels[row] + return lineSpacing + cellViewModel.calcHeight(containerWidth: bounds.width) + } + + public func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { + let view = tableView.makeView(withIdentifier: cellIdentifier, owner: self) as? LyricsCell ?? LyricsCell() + view.update(with: lyricsViewModels[row]) + return view + } +} + +extension LyricsView: NSTableViewDelegate { + private func reloadViewModels() { + scrollViewHadScrolledByUser = false + lyricsViewModels.removeAll() + + guard let lyrics = lyrics?.emptyToNil() else { + tableView.reloadData() + return + } + + parser = LyricsParser(lyrics: lyrics) + + for lyric in parser!.lyrics { + let viewModel = LyricsCellViewModel.cellViewModel(lyric: lyric.text, + font: lyricFont, + highlightedFont: lyricHighlightedFont, + textColor: lyricTextColor, + highlightedTextColor: lyricHighlightedTextColor + ) + lyricsViewModels.append(viewModel) + } + tableView.reloadData() + enclosingScrollView?.contentInsets = NSEdgeInsets(top: frame.height / 2, left: 0, bottom: frame.height / 2, right: 0) + } + + internal func scroll(toTime time: TimeInterval, animated: Bool) { + guard !scrollViewHadScrolledByUser, let lyrics = parser?.lyrics else { + return + } + + guard let index = lyrics.index(where: { $0.time >= time }) else { + // when no lyric is before the time passed in means scrolling to the first + if (lyricsViewModels.count > 0) { + tableView.scrollToBeginningOfDocument(nil) + } + return + } + + guard lastIndex == nil || index - 1 != lastIndex else { + return + } + + if let lastIndex = lastIndex { + lyricsViewModels[lastIndex].highlighted = false + } + + if index > 0 { + lyricsViewModels[index - 1].highlighted = true + tableView.centreRow(row: index - 1, animated: true) + lastIndex = index - 1 + } + } +} + +private extension LyricsView { + @objc func scrollViewDidEndLiveScroll(notification: Notification) { + scrollViewHadScrolledByUser = true + } +} + +private extension NSTableView { + func centreRow(row: Int, animated: Bool) { + selectRowIndexes(IndexSet.init(integer: row), byExtendingSelection: false) + let rowRect = frameOfCell(atColumn: 0, row: row) + if let scrollView = enclosingScrollView { + let centredPoint = NSMakePoint(0.0, rowRect.origin.y + (rowRect.size.height / 2) - ((scrollView.frame.size.height) / 2)) + if animated { + scrollView.contentView.animator().setBoundsOrigin(centredPoint) + } else { + scroll(centredPoint) + } + } + } +} diff --git a/SpotlightLyrics/LyricsView/LyricsCell.swift b/SpotlightLyrics/iOS/LyricsView/LyricsCell.swift similarity index 100% rename from SpotlightLyrics/LyricsView/LyricsCell.swift rename to SpotlightLyrics/iOS/LyricsView/LyricsCell.swift diff --git a/SpotlightLyrics/LyricsView/LyricsCellViewModel.swift b/SpotlightLyrics/iOS/LyricsView/LyricsCellViewModel.swift similarity index 98% rename from SpotlightLyrics/LyricsView/LyricsCellViewModel.swift rename to SpotlightLyrics/iOS/LyricsView/LyricsCellViewModel.swift index e27558b..d7b0631 100644 --- a/SpotlightLyrics/LyricsView/LyricsCellViewModel.swift +++ b/SpotlightLyrics/iOS/LyricsView/LyricsCellViewModel.swift @@ -6,9 +6,7 @@ // Copyright © 2017 Scott Rong. All rights reserved. // -import UIKit - -internal class LyricsCellViewModel { +internal final class LyricsCellViewModel { // MARK: Properties diff --git a/SpotlightLyrics/LyricsView/LyricsView.swift b/SpotlightLyrics/iOS/LyricsView/LyricsView.swift similarity index 99% rename from SpotlightLyrics/LyricsView/LyricsView.swift rename to SpotlightLyrics/iOS/LyricsView/LyricsView.swift index 39a4eb5..cd13486 100644 --- a/SpotlightLyrics/LyricsView/LyricsView.swift +++ b/SpotlightLyrics/iOS/LyricsView/LyricsView.swift @@ -8,7 +8,6 @@ import UIKit - open class LyricsView: UITableView, UITableViewDataSource, UITableViewDelegate { private var parser: LyricsParser? = nil From 9cad9aeef763d9109dfa8981c01ff97488df27ee Mon Sep 17 00:00:00 2001 From: YuantongL Date: Tue, 29 Sep 2020 16:00:29 -0400 Subject: [PATCH 2/3] Allow timer to reset Added a reset() to LyricsViewTimer so that a LyricsView can display lyrics from different song without the needs of re-initialization --- .../ViewController.swift | 18 ++++++- .../ViewController.swift | 54 +++++++++++++------ SpotlightLyrics/Common/LyticsViewTimer.swift | 13 +++-- 3 files changed, 62 insertions(+), 23 deletions(-) diff --git a/Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift b/Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift index a7c63dc..fb086dc 100644 --- a/Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift +++ b/Examples/MacOS/SpotlightLyricsMacExample/ViewController.swift @@ -11,6 +11,8 @@ import SpotlightLyrics /// An example for usage of LyricsView final class ViewController: NSViewController { + private lazy var playButton = NSButton(title: "Play from beginning", target: self, action: #selector(playFromBeginning)) + private lazy var lyricsView: LyricsView = { let lyricsView = LyricsView() if let filepath = Bundle.main.path(forResource: "imagine.lrc", ofType: "txt") { @@ -46,10 +48,22 @@ final class ViewController: NSViewController { NSLayoutConstraint.activate([ lyricsView.leadingAnchor.constraint(equalTo: view.leadingAnchor), lyricsView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - lyricsView.topAnchor.constraint(equalTo: view.topAnchor), - lyricsView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + lyricsView.topAnchor.constraint(equalTo: view.topAnchor) + ]) + + view.addSubview(playButton) + playButton.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + playButton.topAnchor.constraint(equalTo: lyricsView.bottomAnchor), + playButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + playButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8) ]) } + + @objc private func playFromBeginning() { + lyricsView.timer.reset() + lyricsView.timer.play() + } } diff --git a/Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift b/Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift index 2b12e90..6a45b65 100644 --- a/Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift +++ b/Examples/iOS/SpotlightLyricsIOSExample/ViewController.swift @@ -8,23 +8,31 @@ import UIKit import SpotlightLyrics -class ViewController: UIViewController { +final class ViewController: UIViewController { + + private lazy var playButton: UIButton = { + let button = UIButton(frame: .zero) + button.setTitle("Play from beginning", for: .normal) + button.addTarget(self, action: #selector(onPlayFromBeginningButtonTapped), for: .touchUpInside) + button.setTitleColor(.systemBlue, for: .normal) + return button + }() private lazy var lyricsView: LyricsView = { - let lyricsView = LyricsView() - if let filepath = Bundle.main.path(forResource: "imagine.lrc", ofType: "txt") { - do { - let contents = try String(contentsOfFile: filepath) - lyricsView.lyrics = contents - } catch { - assertionFailure("contents could not be loaded") - } - } else { - assertionFailure("txt file not found") + let lyricsView = LyricsView() + if let filepath = Bundle.main.path(forResource: "imagine.lrc", ofType: "txt") { + do { + let contents = try String(contentsOfFile: filepath) + lyricsView.lyrics = contents + } catch { + assertionFailure("contents could not be loaded") } - return lyricsView - }() - + } else { + assertionFailure("txt file not found") + } + return lyricsView + }() + override func viewDidLoad() { super.viewDidLoad() setupLayout() @@ -41,10 +49,22 @@ class ViewController: UIViewController { NSLayoutConstraint.activate([ lyricsView.leadingAnchor.constraint(equalTo: view.leadingAnchor), lyricsView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - lyricsView.topAnchor.constraint(equalTo: view.topAnchor), - lyricsView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + lyricsView.topAnchor.constraint(equalTo: view.topAnchor) + ]) + + view.addSubview(playButton) + playButton.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + playButton.topAnchor.constraint(equalTo: lyricsView.bottomAnchor), + playButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + playButton.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor, constant: -8) ]) } - + + @objc private func onPlayFromBeginningButtonTapped() { + lyricsView.timer.reset() + lyricsView.timer.play() + } + } diff --git a/SpotlightLyrics/Common/LyticsViewTimer.swift b/SpotlightLyrics/Common/LyticsViewTimer.swift index aa6796e..07a6ad7 100644 --- a/SpotlightLyrics/Common/LyticsViewTimer.swift +++ b/SpotlightLyrics/Common/LyticsViewTimer.swift @@ -14,7 +14,7 @@ public final class LyricsViewTimer { internal weak var lyricsView: LyricsView? = nil - private var eplasedTime: TimeInterval = 0 + private var elapsedTime: TimeInterval = 0 // MARK: Controls @@ -35,15 +35,20 @@ public final class LyricsViewTimer { timer = nil } + public func reset() { + pause() + elapsedTime = .zero + } + public func seek(toTime time: TimeInterval) { - eplasedTime = time + elapsedTime = time lyricsView?.scroll(toTime: time, animated: true) } // MARK: tick @objc private func tick() { - eplasedTime += TICK_INTERVAL - seek(toTime: eplasedTime) + elapsedTime += TICK_INTERVAL + seek(toTime: elapsedTime) } } From 9d1b445f631d236ecda53c35d2391d8e14046fb3 Mon Sep 17 00:00:00 2001 From: YuantongL Date: Sat, 31 Oct 2020 01:30:29 -0400 Subject: [PATCH 3/3] Add guard to array index in LyricsViews I've seen crash that these index out of bounds. --- SpotlightLyrics/Mac/LyricsView/LyricsView.swift | 7 +++++-- SpotlightLyrics/iOS/LyricsView/LyricsView.swift | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/SpotlightLyrics/Mac/LyricsView/LyricsView.swift b/SpotlightLyrics/Mac/LyricsView/LyricsView.swift index bbc8f3a..22a16ba 100644 --- a/SpotlightLyrics/Mac/LyricsView/LyricsView.swift +++ b/SpotlightLyrics/Mac/LyricsView/LyricsView.swift @@ -192,11 +192,11 @@ extension LyricsView: NSTableViewDelegate { return } - if let lastIndex = lastIndex { + if let lastIndex = lastIndex, lyricsViewModels.count > lastIndex { lyricsViewModels[lastIndex].highlighted = false } - if index > 0 { + if index > 0, lyricsViewModels.count >= index { lyricsViewModels[index - 1].highlighted = true tableView.centreRow(row: index - 1, animated: true) lastIndex = index - 1 @@ -212,6 +212,9 @@ private extension LyricsView { private extension NSTableView { func centreRow(row: Int, animated: Bool) { + guard numberOfRows > row else { + return + } selectRowIndexes(IndexSet.init(integer: row), byExtendingSelection: false) let rowRect = frameOfCell(atColumn: 0, row: row) if let scrollView = enclosingScrollView { diff --git a/SpotlightLyrics/iOS/LyricsView/LyricsView.swift b/SpotlightLyrics/iOS/LyricsView/LyricsView.swift index cd13486..136cb2e 100644 --- a/SpotlightLyrics/iOS/LyricsView/LyricsView.swift +++ b/SpotlightLyrics/iOS/LyricsView/LyricsView.swift @@ -159,11 +159,11 @@ open class LyricsView: UITableView, UITableViewDataSource, UITableViewDelegate { return } - if let lastIndex = lastIndex { + if let lastIndex = lastIndex, lyricsViewModels.count > lastIndex { lyricsViewModels[lastIndex].highlighted = false } - if index > 0 { + if index > 0, lyricsViewModels.count >= index { lyricsViewModels[index - 1].highlighted = true scrollToRow(at: IndexPath(row: index - 1, section: 0), at: .middle, animated: animated) lastIndex = index - 1