From cda30ebe6242a60df9774547bee96be5a72d0e87 Mon Sep 17 00:00:00 2001 From: DannyFeng Date: Sun, 8 Sep 2024 21:45:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0Widgets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现了Widgets,但是预想中的AppIntents和URL Scheme没有实现 这两个完善之后Widgets会更有用,所以希望至少能够参考一下,或是在这个基础上继续Coding 原本准备全部完善再提交的,但是我明天就要开学了(初三 真的对不起!!!!! --- DarockBili.xcodeproj/project.pbxproj | 223 +++++++++++++++++- MeowBili/Info.plist | 1 + MeowBili/Others/BiliBiliAPIService.swift | 68 ++++++ MeowWidget/Assets.xcassets/Contents.json | 6 + .../Contents.json | 38 +++ .../WidgetTitleColor.colorset/Contents.json | 38 +++ MeowWidget/Info.plist | 11 + MeowWidget/MeowWidget.swift | 162 +++++++++++++ MeowWidget/MeowWidgetBundle.swift | 27 +++ 9 files changed, 572 insertions(+), 2 deletions(-) create mode 100644 MeowBili/Others/BiliBiliAPIService.swift create mode 100644 MeowWidget/Assets.xcassets/Contents.json create mode 100644 MeowWidget/Assets.xcassets/WidgetBackgroundColor.colorset/Contents.json create mode 100644 MeowWidget/Assets.xcassets/WidgetTitleColor.colorset/Contents.json create mode 100644 MeowWidget/Info.plist create mode 100644 MeowWidget/MeowWidget.swift create mode 100644 MeowWidget/MeowWidgetBundle.swift diff --git a/DarockBili.xcodeproj/project.pbxproj b/DarockBili.xcodeproj/project.pbxproj index 7f858bf8c..127012b64 100644 --- a/DarockBili.xcodeproj/project.pbxproj +++ b/DarockBili.xcodeproj/project.pbxproj @@ -200,6 +200,22 @@ 8CC3D5632B7CCE57005636DC /* ScreenshotableView in Frameworks */ = {isa = PBXBuildFile; platformFilters = (ios, maccatalyst, ); productRef = 8CC3D5622B7CCE57005636DC /* ScreenshotableView */; settings = {ATTRIBUTES = (Required, ); }; }; 8CC3D5652B7CCF3C005636DC /* SelfQrCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC3D5642B7CCF3C005636DC /* SelfQrCardView.swift */; }; 8CC5B7432B8749BC00BAD89E /* MeowBiliUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC5B7422B8749BC00BAD89E /* MeowBiliUITests.swift */; }; + B21865642C8DC515006F50C9 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21865632C8DC515006F50C9 /* WidgetKit.framework */; }; + B21865662C8DC515006F50C9 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21865652C8DC515006F50C9 /* SwiftUI.framework */; }; + B21865692C8DC516006F50C9 /* MeowWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21865682C8DC516006F50C9 /* MeowWidgetBundle.swift */; }; + B218656D2C8DC516006F50C9 /* MeowWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = B218656C2C8DC516006F50C9 /* MeowWidget.swift */; }; + B21865712C8DC521006F50C9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B21865702C8DC521006F50C9 /* Assets.xcassets */; }; + B21865752C8DC521006F50C9 /* MeowWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = B21865622C8DC515006F50C9 /* MeowWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + B218657B2C8DC657006F50C9 /* BiliBiliAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B218657A2C8DC657006F50C9 /* BiliBiliAPIService.swift */; }; + B218657C2C8DC657006F50C9 /* BiliBiliAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B218657A2C8DC657006F50C9 /* BiliBiliAPIService.swift */; }; + B218657E2C8DCC3E006F50C9 /* BiliBiliAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B218657A2C8DC657006F50C9 /* BiliBiliAPIService.swift */; }; + B218657F2C8DCC46006F50C9 /* MeowWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = B218656C2C8DC516006F50C9 /* MeowWidget.swift */; }; + B21865802C8DCC46006F50C9 /* MeowWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = B218656C2C8DC516006F50C9 /* MeowWidget.swift */; }; + B21865812C8DDA11006F50C9 /* 喵哩喵哩.app in Resources */ = {isa = PBXBuildFile; fileRef = 8CA7CBCF2B77AC4C008E587F /* 喵哩喵哩.app */; }; + B21865822C8DDA15006F50C9 /* 喵哩喵哩.app in Resources */ = {isa = PBXBuildFile; fileRef = 8CA7CBCF2B77AC4C008E587F /* 喵哩喵哩.app */; platformFilters = (watchos, ); }; + B21865832C8DDA1A006F50C9 /* MeowBili.app in Resources */ = {isa = PBXBuildFile; fileRef = 8CA7CBC02B77AC4A008E587F /* MeowBili.app */; platformFilter = ios; }; + B21865842C8DDA1B006F50C9 /* MeowBili.app in Resources */ = {isa = PBXBuildFile; fileRef = 8CA7CBC02B77AC4A008E587F /* MeowBili.app */; }; + B21865852C8DDA1C006F50C9 /* MeowBili.app in Resources */ = {isa = PBXBuildFile; fileRef = 8CA7CBC02B77AC4A008E587F /* MeowBili.app */; }; B4DAF0DD2B80725800755F0C /* LinkDetectText.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DAF0DB2B80725800755F0C /* LinkDetectText.swift */; }; /* End PBXBuildFile section */ @@ -239,6 +255,13 @@ remoteGlobalIDString = 8CA7CBBF2B77AC4A008E587F; remoteInfo = MeowBili; }; + B21865732C8DC521006F50C9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B44689C42B4FC15A002CCEB2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B21865612C8DC515006F50C9; + remoteInfo = MeowWidgetExtension; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -248,6 +271,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + B21865752C8DC521006F50C9 /* MeowWidgetExtension.appex in Embed Foundation Extensions */, 8C617F562B92334B000A3687 /* SafariExtension.appex in Embed Foundation Extensions */, ); name = "Embed Foundation Extensions"; @@ -377,6 +401,14 @@ 8CD9463A2B64CD0F005D00D0 /* Bangumi_Detail_Season.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = Bangumi_Detail_Season.json; sourceTree = ""; }; 8CFB6B652C650FED007C7BAA /* Watch Debug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Watch Debug.entitlements"; sourceTree = ""; }; 8CFB6B662C650FFE007C7BAA /* Watch Release.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Watch Release.entitlements"; sourceTree = ""; }; + B21865622C8DC515006F50C9 /* MeowWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeowWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + B21865632C8DC515006F50C9 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + B21865652C8DC515006F50C9 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + B21865682C8DC516006F50C9 /* MeowWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeowWidgetBundle.swift; sourceTree = ""; }; + B218656C2C8DC516006F50C9 /* MeowWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeowWidget.swift; sourceTree = ""; }; + B21865702C8DC521006F50C9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B21865722C8DC521006F50C9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B218657A2C8DC657006F50C9 /* BiliBiliAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiliBiliAPIService.swift; sourceTree = ""; }; B4468A152B4FC24A002CCEB2 /* Dynamic_Feed_All.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Dynamic_Feed_All.json; sourceTree = ""; }; B4468A162B4FC24A002CCEB2 /* Search_With_UP_V2.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Search_With_UP_V2.json; sourceTree = ""; }; B4DAF0DB2B80725800755F0C /* LinkDetectText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkDetectText.swift; sourceTree = ""; }; @@ -451,6 +483,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B218655F2C8DC515006F50C9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B21865662C8DC515006F50C9 /* SwiftUI.framework in Frameworks */, + B21865642C8DC515006F50C9 /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -608,6 +649,7 @@ 8CA7CCA02B77B2DC008E587F /* LoginView.swift */, 03B2F80E2C45AED7007EB850 /* PhoneFormatterExt.swift */, 8CA7CCA22B77B2F2008E587F /* NoticeView.swift */, + B218657A2C8DC657006F50C9 /* BiliBiliAPIService.swift */, ); path = Others; sourceTree = ""; @@ -745,6 +787,17 @@ path = Entitlements; sourceTree = ""; }; + B21865672C8DC516006F50C9 /* MeowWidget */ = { + isa = PBXGroup; + children = ( + B21865682C8DC516006F50C9 /* MeowWidgetBundle.swift */, + B218656C2C8DC516006F50C9 /* MeowWidget.swift */, + B21865702C8DC521006F50C9 /* Assets.xcassets */, + B21865722C8DC521006F50C9 /* Info.plist */, + ); + path = MeowWidget; + sourceTree = ""; + }; B44689C32B4FC15A002CCEB2 = { isa = PBXGroup; children = ( @@ -763,6 +816,7 @@ 8C8578A62C5A18AA00AF93D1 /* MeowBiliTests */, 8CC5B7412B8749BC00BAD89E /* MeowBiliUITests */, 8C617F3F2B92334B000A3687 /* SafariExtension */, + B21865672C8DC516006F50C9 /* MeowWidget */, B44689CB2B4FC15A002CCEB2 /* Products */, B4468A902B4FC8B7002CCEB2 /* Frameworks */, ); @@ -776,6 +830,7 @@ 8CC5B7402B8749BC00BAD89E /* MeowBiliUITests.xctest */, 8C617F3E2B92334B000A3687 /* SafariExtension.appex */, 8C2DFCB52C4E6B2B003AEC67 /* MeowBiliTests.xctest */, + B21865622C8DC515006F50C9 /* MeowWidgetExtension.appex */, ); name = Products; sourceTree = ""; @@ -794,6 +849,8 @@ isa = PBXGroup; children = ( 8CC3D5662B7CDCE1005636DC /* Intents.framework */, + B21865632C8DC515006F50C9 /* WidgetKit.framework */, + B21865652C8DC515006F50C9 /* SwiftUI.framework */, ); name = Frameworks; sourceTree = ""; @@ -854,6 +911,7 @@ dependencies = ( 8CA7CBD22B77AC4C008E587F /* PBXTargetDependency */, 8C617F552B92334B000A3687 /* PBXTargetDependency */, + B21865742C8DC521006F50C9 /* PBXTargetDependency */, ); name = MeowBili; packageProductDependencies = ( @@ -932,6 +990,23 @@ productReference = 8CC5B7402B8749BC00BAD89E /* MeowBiliUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; + B21865612C8DC515006F50C9 /* MeowWidgetExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = B21865792C8DC522006F50C9 /* Build configuration list for PBXNativeTarget "MeowWidgetExtension" */; + buildPhases = ( + B218655E2C8DC515006F50C9 /* Sources */, + B218655F2C8DC515006F50C9 /* Frameworks */, + B21865602C8DC515006F50C9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MeowWidgetExtension; + productName = MeowWidgetExtension; + productReference = B21865622C8DC515006F50C9 /* MeowWidgetExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -939,7 +1014,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 1600; + LastSwiftUpdateCheck = 1510; LastUpgradeCheck = 1600; TargetAttributes = { 8C2DFCB42C4E6B2B003AEC67 = { @@ -963,6 +1038,9 @@ CreatedOnToolsVersion = 15.2; TestTargetID = 8CA7CBBF2B77AC4A008E587F; }; + B21865612C8DC515006F50C9 = { + CreatedOnToolsVersion = 15.1; + }; }; }; buildConfigurationList = B44689C72B4FC15A002CCEB2 /* Build configuration list for PBXProject "DarockBili" */; @@ -970,11 +1048,11 @@ developmentRegion = "zh-Hans"; hasScannedForEncodings = 0; knownRegions = ( - Base, "zh-Hans", en, ja, "zh-Hant", + Base, ); mainGroup = B44689C32B4FC15A002CCEB2; packageReferences = ( @@ -1007,6 +1085,7 @@ 8CC5B73F2B8749BC00BAD89E /* MeowBiliUITests */, 8C617F3D2B92334B000A3687 /* SafariExtension */, 8C82F8202BB709E1009AEFD2 /* Alternative Destribution */, + B21865612C8DC515006F50C9 /* MeowWidgetExtension */, ); }; /* End PBXProject section */ @@ -1041,6 +1120,7 @@ 8CA7CBCA2B77AC4C008E587F /* Preview Assets.xcassets in Resources */, 8CA388A22B78B5D800F5F91F /* BiliFont.ttf in Resources */, 8CA7CBC72B77AC4C008E587F /* Assets.xcassets in Resources */, + B21865852C8DDA1C006F50C9 /* MeowBili.app in Resources */, 8C82F7932BB6EAB0009AEFD2 /* SemanticVersion.drkdatas in Resources */, 8CB0D0262B88D67D0057EF1C /* CurrentChannel.drkdatac in Resources */, 8CA370DB2B82724400CE0E9E /* PrivacyInfo.xcprivacy in Resources */, @@ -1055,9 +1135,11 @@ 8C82F7942BB6EAB0009AEFD2 /* SemanticVersion.drkdatas in Resources */, 8CB0D0272B88D67D0057EF1C /* CurrentChannel.drkdatac in Resources */, 8CA388A32B78B5D800F5F91F /* BiliFont.ttf in Resources */, + B21865842C8DDA1B006F50C9 /* MeowBili.app in Resources */, 8CA370DC2B82724400CE0E9E /* PrivacyInfo.xcprivacy in Resources */, 8CA7CCE12B77C3A9008E587F /* Localizable.xcstrings in Resources */, 8CBFF0D32B85E55F00350E0F /* Assets.xcassets in Resources */, + B21865812C8DDA11006F50C9 /* 喵哩喵哩.app in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1068,6 +1150,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B21865602C8DC515006F50C9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B21865832C8DDA1A006F50C9 /* MeowBili.app in Resources */, + B21865712C8DC521006F50C9 /* Assets.xcassets in Resources */, + B21865822C8DDA15006F50C9 /* 喵哩喵哩.app in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -1143,6 +1235,7 @@ 8CA7CCC52B77B47A008E587F /* AudioPlayerView.swift in Sources */, 8CA7CCC82B77B49D008E587F /* ImageViewerView.swift in Sources */, 8CA7CC972B77B115008E587F /* SkinExplorerView.swift in Sources */, + B218657B2C8DC657006F50C9 /* BiliBiliAPIService.swift in Sources */, 8CC3D5582B7CA209005636DC /* UserDynamicListView.swift in Sources */, 8CA7CC712B77AEE4008E587F /* MainView.swift in Sources */, 8CC3D5652B7CCF3C005636DC /* SelfQrCardView.swift in Sources */, @@ -1189,6 +1282,7 @@ 8CA7CC832B77AFF2008E587F /* ErrorGetView.swift in Sources */, 8CA7CC992B77B127008E587F /* SkinDownloadView.swift in Sources */, 8CA7CCDA2B77B55F008E587F /* LiveDetailView.swift in Sources */, + B21865802C8DCC46006F50C9 /* MeowWidget.swift in Sources */, 8CA7CC6C2B77AE80008E587F /* DownloadObj.swift in Sources */, 8CC3D55D2B7CC936005636DC /* OCCodeExt.m in Sources */, 8CA7CCD12B77B504008E587F /* BangumiDetailView.swift in Sources */, @@ -1211,6 +1305,7 @@ 8CBFF0BC2B85E55F00350E0F /* HistoryView.swift in Sources */, 8CBFF0B72B85E55F00350E0F /* ContentView.swift in Sources */, 8CBFF0DB2B85E55F00350E0F /* SignalErrorView.swift in Sources */, + B218657C2C8DC657006F50C9 /* BiliBiliAPIService.swift in Sources */, 8CBFF0D82B85E55F00350E0F /* VideoDetailView.swift in Sources */, 8CBFF0D72B85E55F00350E0F /* MainView.swift in Sources */, 8CBFF0C22B85E55F00350E0F /* WatchLaterView.swift in Sources */, @@ -1257,6 +1352,7 @@ 8CBFF0E92B85E55F00350E0F /* Bangumi.swift in Sources */, 8CBFF0DE2B85E55F00350E0F /* DownloadsView.swift in Sources */, 8CBFF0C92B85E55F00350E0F /* BangumiDownloadView.swift in Sources */, + B218657F2C8DCC46006F50C9 /* MeowWidget.swift in Sources */, 8CBFF0D52B85E55F00350E0F /* SettingsView.swift in Sources */, 8CBFF0BB2B85E55F00350E0F /* DynamicDetailView.swift in Sources */, 8CBFF0E42B85E55F00350E0F /* BangumiDetailView.swift in Sources */, @@ -1271,6 +1367,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B218655E2C8DC515006F50C9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B21865692C8DC516006F50C9 /* MeowWidgetBundle.swift in Sources */, + B218656D2C8DC516006F50C9 /* MeowWidget.swift in Sources */, + B218657E2C8DCC3E006F50C9 /* BiliBiliAPIService.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -1299,6 +1405,11 @@ target = 8CA7CBBF2B77AC4A008E587F /* MeowBili */; targetProxy = 8CC5B7462B8749BC00BAD89E /* PBXContainerItemProxy */; }; + B21865742C8DC521006F50C9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B21865612C8DC515006F50C9 /* MeowWidgetExtension */; + targetProxy = B21865732C8DC521006F50C9 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -1499,6 +1610,7 @@ 8C82F7802BB6DF2D009AEFD2 /* Alternative */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ENABLE_MODULES = YES; @@ -1673,6 +1785,7 @@ 8CA7CBDD2B77AC4D008E587F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ENABLE_MODULES = YES; @@ -1720,6 +1833,7 @@ 8CA7CBDE2B77AC4D008E587F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ENABLE_MODULES = YES; @@ -1891,6 +2005,101 @@ }; name = Release; }; + B21865762C8DC522006F50C9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B57D8PP775; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeowWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeowWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.darock.DarockBili.MeowWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator watchos watchsimulator"; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,4"; + }; + name = Debug; + }; + B21865772C8DC522006F50C9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B57D8PP775; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeowWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeowWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.darock.DarockBili.MeowWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator watchos watchsimulator"; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,4"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B21865782C8DC522006F50C9 /* Alternative */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B38QUJMY47; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MeowWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = MeowWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.darock.DarockBili.MeowWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator watchos watchsimulator"; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,4"; + VALIDATE_PRODUCT = YES; + }; + name = Alternative; + }; B44689DE2B4FC15B002CCEB2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2080,6 +2289,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + B21865792C8DC522006F50C9 /* Build configuration list for PBXNativeTarget "MeowWidgetExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B21865762C8DC522006F50C9 /* Debug */, + B21865772C8DC522006F50C9 /* Release */, + B21865782C8DC522006F50C9 /* Alternative */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; B44689C72B4FC15A002CCEB2 /* Build configuration list for PBXProject "DarockBili" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/MeowBili/Info.plist b/MeowBili/Info.plist index acf7abaee..e0660c6df 100644 --- a/MeowBili/Info.plist +++ b/MeowBili/Info.plist @@ -9,6 +9,7 @@ Editor CFBundleURLSchemes + meowbili drkbili diff --git a/MeowBili/Others/BiliBiliAPIService.swift b/MeowBili/Others/BiliBiliAPIService.swift new file mode 100644 index 000000000..2df0b816a --- /dev/null +++ b/MeowBili/Others/BiliBiliAPIService.swift @@ -0,0 +1,68 @@ +// +// +// BiliBiliAPIService.swift +// DarockBili +// +// Created by feng on 9/8/24. +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the MeowBili open source project +// +// Copyright (c) 2024 Darock Studio and the MeowBili project authors +// Licensed under GNU General Public License v3 +// +// See https://darock.top/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +import Foundation + +class BiliBiliAPIService { + + enum ContentType { + case trending, recommendations + } + + /// 获取BiliBili数据 + /// - Parameters: + /// - type: 内容类型(热门或推荐) + /// - limit: 限制返回的视频数量,默认是5 + func fetchBiliBiliData(for type: ContentType, limit: Int = 5) async -> Result<[(title: String, description: String, author: String, views: String)], Error> { + do { + let urlString: String + switch type { + case .trending: + urlString = "https://api.bilibili.com/x/web-interface/popular?ps=\(limit)" + case .recommendations: + urlString = "https://api.bilibili.com/x/web-interface/index/top/rcmd?ps=1" + } + + guard let url = URL(string: urlString) else { + throw URLError(.badURL) + } + + let (data, _) = try await URLSession.shared.data(from: url) + + if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], + let dataDict = json["data"] as? [String: Any], + let list = dataDict["list"] as? [[String: Any]] { + + let videos = list.prefix(limit).map { video -> (String, String, String, String) in + let videoTitle = video["title"] as? String ?? "无标题" + let videoDesc = video["desc"] as? String ?? "无描述" + let videoAuthor = video["author"] as? String ?? "未知作者" + let videoViews = video["view"] as? String ?? "未知播放量" + return (title: videoTitle, description: videoDesc, author: videoAuthor, views: videoViews) + } + + return .success(videos) + } else { + return .failure(NSError(domain: "BiliBiliAPIService", code: -1, userInfo: [NSLocalizedDescriptionKey: "数据格式错误"])) + } + + } catch { + return .failure(error) + } + } +} diff --git a/MeowWidget/Assets.xcassets/Contents.json b/MeowWidget/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/MeowWidget/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MeowWidget/Assets.xcassets/WidgetBackgroundColor.colorset/Contents.json b/MeowWidget/Assets.xcassets/WidgetBackgroundColor.colorset/Contents.json new file mode 100644 index 000000000..806450676 --- /dev/null +++ b/MeowWidget/Assets.xcassets/WidgetBackgroundColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "255", + "red" : "255" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "26", + "green" : "24", + "red" : "23" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MeowWidget/Assets.xcassets/WidgetTitleColor.colorset/Contents.json b/MeowWidget/Assets.xcassets/WidgetTitleColor.colorset/Contents.json new file mode 100644 index 000000000..f47b17e1d --- /dev/null +++ b/MeowWidget/Assets.xcassets/WidgetTitleColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "153", + "green" : "103", + "red" : "255" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "126", + "green" : "79", + "red" : "212" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MeowWidget/Info.plist b/MeowWidget/Info.plist new file mode 100644 index 000000000..0f118fb75 --- /dev/null +++ b/MeowWidget/Info.plist @@ -0,0 +1,11 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/MeowWidget/MeowWidget.swift b/MeowWidget/MeowWidget.swift new file mode 100644 index 000000000..dc9b6fafa --- /dev/null +++ b/MeowWidget/MeowWidget.swift @@ -0,0 +1,162 @@ +// +// +// MeowWidget.swift +// MeowWidgetExtension +// +// Created by feng on 9/8/24. +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the MeowBili open source project +// +// Copyright (c) 2024 Darock Studio and the MeowBili project authors +// Licensed under GNU General Public License v3 +// +// See https://darock.top/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +import WidgetKit +import SwiftUI +import Intents + +struct MeowWidgetEntry: TimelineEntry { + let date: Date + let videoTitle: String + let videoDescription: String + let videoAuthor: String + let videoViews: String +} + +struct Provider: TimelineProvider { + func placeholder(in context: Context) -> MeowWidgetEntry { + MeowWidgetEntry(date: Date(), videoTitle: "视频名称", videoDescription: "描述", videoAuthor: "作者", videoViews: "播放量") + } + + func getSnapshot(in context: Context, completion: @escaping (MeowWidgetEntry) -> ()) { + let entry = MeowWidgetEntry(date: Date(), videoTitle: "视频名称", videoDescription: "描述", videoAuthor: "作者", videoViews: "播放量") + completion(entry) + } + + func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { + Task { + let trendingResult = await BiliBiliAPIService().fetchBiliBiliData(for: .trending, limit: 5) + let recommendationsResult = await BiliBiliAPIService().fetchBiliBiliData(for: .recommendations, limit: 5) + + var allVideos: [(title: String, description: String, author: String, views: String)] = [] + if case .success(let trendingVideos) = trendingResult { + allVideos.append(contentsOf: trendingVideos) + } + if case .success(let recommendationsVideos) = recommendationsResult { + allVideos.append(contentsOf: recommendationsVideos) + } + + if !allVideos.isEmpty { + var entries: [MeowWidgetEntry] = [] + let currentDate = Date() + + // 每隔 10 分钟轮播一个视频标题 + for (index, video) in allVideos.enumerated() { + let entryDate = Calendar.current.date(byAdding: .minute, value: index * 10, to: currentDate) ?? currentDate + let entry = MeowWidgetEntry( + date: entryDate, + videoTitle: video.title, + videoDescription: video.description, + videoAuthor: video.author, + videoViews: video.views + ) + entries.append(entry) + } + + let nextUpdateDate = Calendar.current.date(byAdding: .hour, value: 1, to: currentDate) ?? currentDate + let timeline = Timeline(entries: entries, policy: .after(nextUpdateDate)) + completion(timeline) + } else { + let entry = MeowWidgetEntry(date: Date(), videoTitle: "暂无数据", videoDescription: "", videoAuthor: "", videoViews: "") + completion(Timeline(entries: [entry], policy: .atEnd)) + } + } + } +} + +struct MeowWidgetEntryView : View { + var entry: Provider.Entry + @Environment(\.widgetFamily) var family + + var body: some View { + VStack(alignment: .leading) { + HStack { + Image("MeowBili") + .resizable() + .frame(width: 24, height: 24) + Text("喵哩喵哩") + .font(.headline) + .foregroundColor(Color("WidgetTitleColor")) + } + + Spacer().frame(height: 10) + + switch family { + case .systemSmall: + Text(entry.videoTitle) + .font(.headline) + + case .systemMedium: + Text(entry.videoTitle) + .font(.headline) + Text(entry.videoDescription) + .font(.subheadline) + Spacer() + Text("在喵哩喵哩查看更多内容") + .font(.footnote) + .foregroundColor(.gray) + + case .systemLarge: + Text(entry.videoTitle) + .font(.headline) + Text(entry.videoDescription) + .font(.subheadline) + Text("作者: \(entry.videoAuthor)") + .font(.footnote) + Text("播放量: \(entry.videoViews)") + .font(.footnote) + Spacer() + Text("在喵哩喵哩查看更多内容") + .font(.footnote) + .foregroundColor(.gray) + + case .accessoryCircular, .accessoryRectangular: + if entry.videoTitle == "打开喵哩喵哩" { + Text("打开喵哩喵哩") + .font(.headline) + } else { + Text(entry.videoTitle) + .font(.headline) + } + + default: + Text(entry.videoTitle) + .font(.headline) + Text(entry.videoDescription) + .font(.subheadline) + } + } + .padding() + .background(Color("WidgetBackgroundColor")) + .widgetURL(URL(string: "meowbili://")!) + } +} + + +struct MeowWidget: Widget { + let kind: String = "MeowWidget" + + var body: some WidgetConfiguration { + StaticConfiguration(kind: kind, provider: Provider()) { entry in + MeowWidgetEntryView(entry: entry) + } + .configurationDisplayName("喵哩喵哩Widget") + .description("热门或推荐的视频内容") + .supportedFamilies([.systemSmall, .systemMedium, .systemLarge, .accessoryCircular, .accessoryRectangular]) + } +} diff --git a/MeowWidget/MeowWidgetBundle.swift b/MeowWidget/MeowWidgetBundle.swift new file mode 100644 index 000000000..2ed610cac --- /dev/null +++ b/MeowWidget/MeowWidgetBundle.swift @@ -0,0 +1,27 @@ +// +// +// MeowWidgetBundle.swift +// MeowWidgetExtension +// +// Created by feng on 9/8/24. +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the MeowBili open source project +// +// Copyright (c) 2024 Darock Studio and the MeowBili project authors +// Licensed under GNU General Public License v3 +// +// See https://darock.top/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +import WidgetKit +import SwiftUI + +@main +struct MeowWidgetBundle: WidgetBundle { + var body: some Widget { + MeowWidget() + } +}