反馈,注销,推送,adjust

This commit is contained in:
澜声世纪 2025-12-17 18:04:38 +08:00
parent 5c9c5d64b6
commit 22f2e9febf
245 changed files with 1754 additions and 535 deletions

View File

@ -33,6 +33,9 @@ target 'ReaderHive' do
pod 'Toast'
pod 'SVProgressHUD'
pod 'FDFullscreenPopGesture'
pod 'ZLPhotoBrowser'
pod 'JXIAPManager', :git => 'https://git.qinjiu8.com/zengjx/JXIAPManager.git', :tag => '0.0.1'
pod 'Adjust'
end

View File

@ -111,6 +111,17 @@
85CF944B2EF004D3006467E3 /* NRMyUnlocksCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF94482EF004D3006467E3 /* NRMyUnlocksCell.swift */; };
85CF944D2EF0EC00006467E3 /* NRVersionUpdateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF944C2EF0EC00006467E3 /* NRVersionUpdateModel.swift */; };
85CF944F2EF0F04D006467E3 /* NRUpdatesAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF944E2EF0F04D006467E3 /* NRUpdatesAlert.swift */; };
85CF94522EF14FBD006467E3 /* NROpenAppManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF94512EF14FA3006467E3 /* NROpenAppManager.swift */; };
85CF94542EF151E4006467E3 /* NRAppStartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF94532EF151E4006467E3 /* NRAppStartViewController.swift */; };
85CF94562EF15F7C006467E3 /* NRFeedbackCountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF94552EF15F7C006467E3 /* NRFeedbackCountModel.swift */; };
85CF94582EF25694006467E3 /* NRCoinPackCanReceiveModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF94572EF25694006467E3 /* NRCoinPackCanReceiveModel.swift */; };
85CF945A2EF257B9006467E3 /* NRCoinsPackAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF94592EF257B9006467E3 /* NRCoinsPackAlert.swift */; };
85CF945C2EF28433006467E3 /* NROpenAppModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF945B2EF28433006467E3 /* NROpenAppModel.swift */; };
85CF945E2EF285D5006467E3 /* NRStatAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF945D2EF285D2006467E3 /* NRStatAPI.swift */; };
85CF94612EF2A347006467E3 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 85CF94602EF2A347006467E3 /* FirebaseMessaging */; };
85CF94632EF2A347006467E3 /* FirebasePerformance in Frameworks */ = {isa = PBXBuildFile; productRef = 85CF94622EF2A347006467E3 /* FirebasePerformance */; };
85CF94652EF2A3D9006467E3 /* AppDelegate+APNS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CF94642EF2A3D3006467E3 /* AppDelegate+APNS.swift */; };
85CF94672EF2A81D006467E3 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 85CF94662EF2A81D006467E3 /* GoogleService-Info.plist */; };
F34348AF2ED5B85300AA7E70 /* NRExploreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F34348AE2ED5B85300AA7E70 /* NRExploreViewController.swift */; };
F34348B12ED5B9A400AA7E70 /* NRExploreNovelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F34348B02ED5B9A400AA7E70 /* NRExploreNovelViewController.swift */; };
F34348B32ED5BB6100AA7E70 /* NRExploreNovelMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F34348B22ED5BB6100AA7E70 /* NRExploreNovelMenuView.swift */; };
@ -213,7 +224,6 @@
F3B859442EE902BF0095A9CC /* NRStoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B859432EE902BF0095A9CC /* NRStoreViewController.swift */; };
F3B8594C2EE904980095A9CC /* NRPayDateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B8594B2EE904980095A9CC /* NRPayDateModel.swift */; };
F3B8594E2EE905A70095A9CC /* NRStoreAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B8594D2EE905A40095A9CC /* NRStoreAPI.swift */; };
F3B859522EE906A90095A9CC /* JXIAPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B859512EE906A80095A9CC /* JXIAPManager.swift */; };
F3B859572EE9072C0095A9CC /* NRIapManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B859562EE907280095A9CC /* NRIapManager.swift */; };
F3B859592EE9073B0095A9CC /* NRIAPOrderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B859582EE907350095A9CC /* NRIAPOrderModel.swift */; };
F3B8595B2EE907600095A9CC /* NRWaitRestoreModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B8595A2EE907600095A9CC /* NRWaitRestoreModel.swift */; };
@ -357,6 +367,15 @@
85CF94492EF004D3006467E3 /* NRMyUnlocksCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NRMyUnlocksCell.xib; sourceTree = "<group>"; };
85CF944C2EF0EC00006467E3 /* NRVersionUpdateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRVersionUpdateModel.swift; sourceTree = "<group>"; };
85CF944E2EF0F04D006467E3 /* NRUpdatesAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRUpdatesAlert.swift; sourceTree = "<group>"; };
85CF94512EF14FA3006467E3 /* NROpenAppManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NROpenAppManager.swift; sourceTree = "<group>"; };
85CF94532EF151E4006467E3 /* NRAppStartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRAppStartViewController.swift; sourceTree = "<group>"; };
85CF94552EF15F7C006467E3 /* NRFeedbackCountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRFeedbackCountModel.swift; sourceTree = "<group>"; };
85CF94572EF25694006467E3 /* NRCoinPackCanReceiveModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRCoinPackCanReceiveModel.swift; sourceTree = "<group>"; };
85CF94592EF257B9006467E3 /* NRCoinsPackAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRCoinsPackAlert.swift; sourceTree = "<group>"; };
85CF945B2EF28433006467E3 /* NROpenAppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NROpenAppModel.swift; sourceTree = "<group>"; };
85CF945D2EF285D2006467E3 /* NRStatAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRStatAPI.swift; sourceTree = "<group>"; };
85CF94642EF2A3D3006467E3 /* AppDelegate+APNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+APNS.swift"; sourceTree = "<group>"; };
85CF94662EF2A81D006467E3 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
C3BEE224CB3F55939653D26D /* Pods-NovelReader.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NovelReader.debug.xcconfig"; path = "Target Support Files/Pods-NovelReader/Pods-NovelReader.debug.xcconfig"; sourceTree = "<group>"; };
F34348AE2ED5B85300AA7E70 /* NRExploreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRExploreViewController.swift; sourceTree = "<group>"; };
F34348B02ED5B9A400AA7E70 /* NRExploreNovelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRExploreNovelViewController.swift; sourceTree = "<group>"; };
@ -460,7 +479,6 @@
F3B859432EE902BF0095A9CC /* NRStoreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRStoreViewController.swift; sourceTree = "<group>"; };
F3B8594B2EE904980095A9CC /* NRPayDateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRPayDateModel.swift; sourceTree = "<group>"; };
F3B8594D2EE905A40095A9CC /* NRStoreAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRStoreAPI.swift; sourceTree = "<group>"; };
F3B859512EE906A80095A9CC /* JXIAPManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JXIAPManager.swift; sourceTree = "<group>"; };
F3B859562EE907280095A9CC /* NRIapManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRIapManager.swift; sourceTree = "<group>"; };
F3B859582EE907350095A9CC /* NRIAPOrderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRIAPOrderModel.swift; sourceTree = "<group>"; };
F3B8595A2EE907600095A9CC /* NRWaitRestoreModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NRWaitRestoreModel.swift; sourceTree = "<group>"; };
@ -499,7 +517,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
85CF94612EF2A347006467E3 /* FirebaseMessaging in Frameworks */,
85CF94372EEFE27E006467E3 /* FacebookLogin in Frameworks */,
85CF94632EF2A347006467E3 /* FirebasePerformance in Frameworks */,
67DC33BD353DB9F2D4C0FFE8 /* Pods_ReaderHive.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -510,6 +530,7 @@
0373D93C2ED578FC0017DCC7 /* API */ = {
isa = PBXGroup;
children = (
85CF945D2EF285D2006467E3 /* NRStatAPI.swift */,
F3B8594D2EE905A40095A9CC /* NRStoreAPI.swift */,
F34991022EE160E50039E939 /* NRUserAPI.swift */,
F343492B2EDE72EE00AA7E70 /* NRHomeAPI.swift */,
@ -635,6 +656,7 @@
children = (
03980F7E2ED009EB0006E317 /* Assets.xcassets */,
03980F7F2ED009EB0006E317 /* Info.plist */,
85CF94662EF2A81D006467E3 /* GoogleService-Info.plist */,
03980F812ED009EB0006E317 /* LaunchScreen.storyboard */,
039810712ED053BE0006E317 /* Localizable.strings */,
);
@ -648,6 +670,7 @@
03980F842ED009EB0006E317 /* SceneDelegate.swift */,
0398107B2ED0551C0006E317 /* AppDelegate+Config.swift */,
85CF943A2EEFE947006467E3 /* AppDelegate+Open.swift */,
85CF94642EF2A3D3006467E3 /* AppDelegate+APNS.swift */,
);
path = Delegate;
sourceTree = "<group>";
@ -685,6 +708,7 @@
0398105B2ED047FE0006E317 /* NRTabBarController.swift */,
0398105D2ED0481E0006E317 /* NRNavigationController.swift */,
0398108F2ED060EF0006E317 /* NRViewController.swift */,
85CF94532EF151E4006467E3 /* NRAppStartViewController.swift */,
);
path = VC;
sourceTree = "<group>";
@ -794,6 +818,8 @@
isa = PBXGroup;
children = (
039810972ED066B20006E317 /* NRTool.swift */,
85CF94512EF14FA3006467E3 /* NROpenAppManager.swift */,
85CF945B2EF28433006467E3 /* NROpenAppModel.swift */,
);
path = Tool;
sourceTree = "<group>";
@ -1047,6 +1073,7 @@
F34991042EE165EA0039E939 /* NRMeItem.swift */,
F3B8593B2EE677170095A9CC /* NRLanguageModel.swift */,
85CF944C2EF0EC00006467E3 /* NRVersionUpdateModel.swift */,
85CF94552EF15F7C006467E3 /* NRFeedbackCountModel.swift */,
);
path = M;
sourceTree = "<group>";
@ -1113,6 +1140,7 @@
children = (
F34991222EE26EAC0039E939 /* NRAlert.swift */,
85CF944E2EF0F04D006467E3 /* NRUpdatesAlert.swift */,
85CF94592EF257B9006467E3 /* NRCoinsPackAlert.swift */,
F349911E2EE26C350039E939 /* NRAlertWindowManager.swift */,
F34991202EE26C660039E939 /* NRBaseAlert.swift */,
);
@ -1175,6 +1203,7 @@
F3B859922EEA63CD0095A9CC /* NROrderRecordsModel.swift */,
85CF941C2EEBFEA6006467E3 /* NRCoinsPackModel.swift */,
85CF941E2EEBFECF006467E3 /* NRCoinsPackReceiveModel.swift */,
85CF94572EF25694006467E3 /* NRCoinPackCanReceiveModel.swift */,
);
path = M;
sourceTree = "<group>";
@ -1196,19 +1225,10 @@
F3B8594F2EE9068E0095A9CC /* Thirdparty */ = {
isa = PBXGroup;
children = (
F3B859502EE906A40095A9CC /* JXIAPManager */,
);
path = Thirdparty;
sourceTree = "<group>";
};
F3B859502EE906A40095A9CC /* JXIAPManager */ = {
isa = PBXGroup;
children = (
F3B859512EE906A80095A9CC /* JXIAPManager.swift */,
);
path = JXIAPManager;
sourceTree = "<group>";
};
F3B859552EE907220095A9CC /* IAP */ = {
isa = PBXGroup;
children = (
@ -1270,6 +1290,7 @@
minimizedProjectReferenceProxies = 1;
packageReferences = (
85CF94352EEFE27E006467E3 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */,
85CF945F2EF2A347006467E3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 03980F662ED009E30006E317 /* Products */;
@ -1292,6 +1313,7 @@
F3B859872EE972F70095A9CC /* NRConsumptionRecordsCell.xib in Resources */,
03980F8C2ED009EB0006E317 /* LaunchScreen.storyboard in Resources */,
85CF944A2EF004D3006467E3 /* NRMyUnlocksCell.xib in Resources */,
85CF94672EF2A81D006467E3 /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1372,6 +1394,7 @@
85CF94212EEC050D006467E3 /* NRCoinsPackBuyView.swift in Sources */,
F3B8595F2EE910020095A9CC /* NRPayDataRequest.swift in Sources */,
F3B859692EE91BD70095A9CC /* NRStoreCoinsPackCell.swift in Sources */,
85CF945E2EF285D5006467E3 /* NRStatAPI.swift in Sources */,
F34991102EE1708C0039E939 /* NRWebViewController+Script.swift in Sources */,
F34348B12ED5B9A400AA7E70 /* NRExploreNovelViewController.swift in Sources */,
F34348BF2ED691C100AA7E70 /* NRExploreNovelGenresViewController.swift in Sources */,
@ -1403,6 +1426,7 @@
85CF94272EED1734006467E3 /* NRHomeCoinsPackButton.swift in Sources */,
F34991012EE1593A0039E939 /* NRMeHeaderView.swift in Sources */,
F3B8598F2EEA5B1C0095A9CC /* NROrderRecordsPageViewController.swift in Sources */,
85CF94542EF151E4006467E3 /* NRAppStartViewController.swift in Sources */,
F34991052EE165EA0039E939 /* NRMeItem.swift in Sources */,
039810CC2ED477CD0006E317 /* UIView+NRAdd.swift in Sources */,
F3B859312EE66B950095A9CC /* NRDetailRechargeView.swift in Sources */,
@ -1414,8 +1438,10 @@
F3B8595B2EE907600095A9CC /* NRWaitRestoreModel.swift in Sources */,
039810CA2ED469D50006E317 /* NRWaterfallFlowLayout.swift in Sources */,
F34348F72ED84B0D00AA7E70 /* NRNovelReaderViewController+Page.swift in Sources */,
85CF94582EF25694006467E3 /* NRCoinPackCanReceiveModel.swift in Sources */,
039810902ED060EF0006E317 /* NRViewController.swift in Sources */,
039810702ED053910006E317 /* String+NRAdd.swift in Sources */,
85CF94652EF2A3D9006467E3 /* AppDelegate+APNS.swift in Sources */,
039810932ED062CE0006E317 /* NRHomeViewController.swift in Sources */,
F3B859652EE91BB70095A9CC /* NRStoreCoinsBigCell.swift in Sources */,
039810BC2ED43C8E0006E317 /* NRReadWhatViewTransformer.swift in Sources */,
@ -1450,6 +1476,7 @@
85606A9C2EEBE243005D989D /* NRCoinsPackHeaderView.swift in Sources */,
F34349102ED9A77A00AA7E70 /* NRPanModalContentView.swift in Sources */,
F3B859892EE97E1F0095A9CC /* NRRewardCoinsViewController.swift in Sources */,
85CF945C2EF28433006467E3 /* NROpenAppModel.swift in Sources */,
039810CE2ED47A130006E317 /* CGMutablePath+NRRoundedCorner.swift in Sources */,
F34348E72ED7F91C00AA7E70 /* NSNumber+NRAdd.swift in Sources */,
F3B8597F2EE96F810095A9CC /* NRConsumptionRecordsViewController.swift in Sources */,
@ -1473,9 +1500,9 @@
F3B859372EE6750B0095A9CC /* NRLanguageViewController.swift in Sources */,
F34348E12ED70A2700AA7E70 /* NRNovelDetailHeaderView+NovelCoverInfo.swift in Sources */,
85CF94292EED4664006467E3 /* NRVipRetainAlert.swift in Sources */,
F3B859522EE906A90095A9CC /* JXIAPManager.swift in Sources */,
F34349012ED93A9B00AA7E70 /* NRReadChapterModel.swift in Sources */,
F34348DF2ED7049E00AA7E70 /* NRNovelDetailHeaderView.swift in Sources */,
85CF94562EF15F7C006467E3 /* NRFeedbackCountModel.swift in Sources */,
F34348BB2ED5CD8100AA7E70 /* NRExploreNovelMenuItem.swift in Sources */,
0398109B2ED0692A0006E317 /* NRImageView.swift in Sources */,
0398108A2ED0582F0006E317 /* NRDeviceId.swift in Sources */,
@ -1549,10 +1576,12 @@
F3B8597D2EE9627B0095A9CC /* NRWalletHeaderView.swift in Sources */,
039810872ED057260006E317 /* NRUserDefaultsKey.swift in Sources */,
F34349222EDD227A00AA7E70 /* NRReadSettingSpacingView.swift in Sources */,
85CF94522EF14FBD006467E3 /* NROpenAppManager.swift in Sources */,
85606A902EEBA8F3005D989D /* NRCoinsPackConfirmView.swift in Sources */,
F34990F32EE02FD60039E939 /* NRNovelReadFinishViewController.swift in Sources */,
F34348F92ED855AA00AA7E70 /* NRNovelReadContentViewController.swift in Sources */,
039810A42ED072380006E317 /* NRHomeNovelListViewController.swift in Sources */,
85CF945A2EF257B9006467E3 /* NRCoinsPackAlert.swift in Sources */,
039810BE2ED44C210006E317 /* NRHomeNovelHotGridView.swift in Sources */,
F3B859672EE91BC50095A9CC /* NRStoreCoinsSmallCell.swift in Sources */,
F3B859392EE676610095A9CC /* NRLanguageCell.swift in Sources */,
@ -1622,6 +1651,7 @@
INFOPLIST_KEY_LSApplicationCategoryType = "";
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience.";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = "";
@ -1632,7 +1662,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.lssj.ReaderHive;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1666,6 +1696,7 @@
INFOPLIST_KEY_LSApplicationCategoryType = "";
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience.";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = "";
@ -1676,7 +1707,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.lssj.ReaderHive;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1845,6 +1876,14 @@
minimumVersion = 14.1.0;
};
};
85CF945F2EF2A347006467E3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 12.7.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@ -1853,6 +1892,16 @@
package = 85CF94352EEFE27E006467E3 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */;
productName = FacebookLogin;
};
85CF94602EF2A347006467E3 /* FirebaseMessaging */ = {
isa = XCSwiftPackageProductDependency;
package = 85CF945F2EF2A347006467E3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseMessaging;
};
85CF94622EF2A347006467E3 /* FirebasePerformance */ = {
isa = XCSwiftPackageProductDependency;
package = 85CF945F2EF2A347006467E3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebasePerformance;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 03980F5D2ED009E30006E317 /* Project object */;

View File

@ -2,7 +2,7 @@
// NRDefine.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRUserDefaultsKey.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
///token
@ -15,3 +15,7 @@ let kNRNovelReadSetDefaultsKey = "kNRNovelReadSetDefaultsKey"
let kNRWaitRestoreIAPDefaultsKey = "kNRWaitRestoreIAPDefaultsKey"
let kNRVersionUpdateAlertDefaultsKey = "kNRVersionUpdateAlertDefaultsKey"
let kNRHasFirstOpenedAPPDefaultsKey = "kNRHasFirstOpenedAPPDefaultsKey"
let kNRApnsAlertDefaultsKey = "kNRApnsAlertDefaultsKey"

View File

@ -2,7 +2,7 @@
// CGMutablePath+NRRoundedCorner.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// Dictionary+NRAdd.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/10.
// Created by on 2025/12/10.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NSNumber+NRAdd.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/27.
// Created by on 2025/11/27.
//
import UIKit

View File

@ -2,7 +2,7 @@
// String+NRAdd.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit
import YYCategories
@ -42,3 +42,23 @@ extension String {
} catch {return []}
}
}
extension String {
///url
func nr_urlQuryToDictionary() -> [String : Any] {
let array = self.components(separatedBy: "&")
var tempDic: [String : Any] = [:]
array.forEach {
if let strRange = $0.range(of: "=") {
var key: String = String($0.prefix(upTo: strRange.upperBound))
key.removeLast()
var value: String = String($0.suffix(from: strRange.upperBound))
value = value.removingPercentEncoding ?? value
tempDic[key] = value
}
}
return tempDic
}
}

View File

@ -2,7 +2,7 @@
// UIFont+NRAdd.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// UINavigationBar+NRAdd.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// UIScreen+NRAdd.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// UIScrollView+Refresh.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/2.
// Created by on 2025/12/2.
//
import UIKit

View File

@ -2,7 +2,7 @@
// UIStackView+NRAdd.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// UIView+NRAdd.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// UserDefaults+NRAdd.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeAPI.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/2.
// Created by on 2025/12/2.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRNovelAPI.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit
@ -233,6 +233,26 @@ struct NRNovelAPI {
}
}
static func requestMyUnlock(page: Int) async -> [NRNovelModel]? {
await withCheckedContinuation { continuation in
var param = NRNetwork.Parameters(path: "/novel/purchasedNovels")
param.method = .get
param.parameters = [
"current_page" : page,
"page_size" : 20
]
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRNetwork.List<NRNovelModel>>) in
if response.isSuccess {
continuation.resume(returning: response.data?.list)
} else {
continuation.resume(returning: nil)
}
}
}
}
}

View File

@ -2,7 +2,7 @@
// NRSettingAPI.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/8.
// Created by on 2025/12/8.
//
import UIKit
@ -61,4 +61,24 @@ struct NRSettingAPI {
}
}
///
static func requestFeedbackRedCount() async -> NRFeedbackCountModel? {
await withCheckedContinuation { continuation in
var param = NRNetwork.Parameters(path: "/noticeNum")
param.method = .post
param.isToast = false
param.isLoding = false
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRFeedbackCountModel>) in
if response.isSuccess {
continuation.resume(returning: response.data)
} else {
continuation.resume(returning: nil)
}
}
}
}
}

View File

@ -0,0 +1,171 @@
//
// NRStatAPI.swift
// ReaderHive
//
// Created by on 2025/12/17.
//
import UIKit
import Alamofire
struct NRStatAPI {
enum EventKey: String {
case payError = "pay_error" //
case payCallback = "pay_callback" //
case payRestore = "pay_restore" //restore
case forceUpdate = "force_update"//
case payCancel = "pay_cancel" //
case payTemplateDialog = "pay_template_dialog"//
}
///w2a
static func nr_requestStatW2a(data: String) {
let parameters = [
"data" : data
]
var param = NRNetwork.Parameters(path: "/w2aSelfAttribution")
param.method = .post
param.isLoding = false
param.isToast = false
param.parameters = parameters
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
///
static func nr_requestEventStat(orderCode: String?, shortPlayId: String?, videoId: String?, eventKey: EventKey, errorMsg: String?, otherParamenters: [String : Any]? = nil) {
var eventName = ""
switch eventKey {
case .payRestore:
eventName = "pay restore"
case .payCallback:
eventName = "pay callback failed"
case .forceUpdate:
eventName = "force update"
case .payCancel:
eventName = "user pay canceled"
default:
eventName = "platform pay failed"
}
var parameters: [String : Any] = [
"userId" : NRLoginManager.manager.userInfo?.customer_id ?? "",
"short_play_video_id" : videoId ?? "0",
"short_play_id" : shortPlayId ?? "0",
"event_key" : eventKey.rawValue,
"order_code": orderCode ?? "",
"event_name" : eventName,
]
if let errorMsg = errorMsg {
parameters["error_msg"] = errorMsg
}
if let otherParamenters = otherParamenters {
otherParamenters.forEach {
parameters[$0] = $1
}
}
var param = NRNetwork.Parameters(path: "/event/add")
param.method = .post
param.isLoding = false
param.isToast = false
param.parameters = parameters
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
///APP
static func nr_requestEnterApp() {
var param = NRNetwork.Parameters(path: "/customer/enterTheApp")
param.method = .post
param.isLoding = false
param.isToast = false
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
///APP
static func nr_requestLeaveApp() {
var param = NRNetwork.Parameters(path: "/customer/leaveApp")
param.method = .post
param.isLoding = false
param.isToast = false
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
static func nr_requestStatOnLine() {
var param = NRNetwork.Parameters(path: "/customer/onLine")
param.method = .post
param.isLoding = false
param.isToast = false
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
static func nr_requestUploadApnsAuthorizationStatus(_ status: Bool) {
let parameters = [
"is_open_notice" : status ? 1 : 0
]
var param = NRNetwork.Parameters(path: "/customer/uploadNoticeStatus")
param.method = .post
param.isLoding = false
param.isToast = false
param.parameters = parameters
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
static func nr_requestStatApnsClick(id: String, title: String) {
let parameters = [
"message_id" : id,
"title" : title
]
var param = NRNetwork.Parameters(path: "/message/sendReport")
param.method = .post
param.isLoding = false
param.isToast = false
param.parameters = parameters
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
static func nr_requestUploadApnsDeviceToken(token: String) {
let parameters = [
"fcm_token": token
]
var param = NRNetwork.Parameters(path: "/customer/firebaseToken")
param.method = .post
param.isLoding = false
param.isToast = false
param.parameters = parameters
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in }
}
}
extension NRStatAPI {
///
static func nr_uploadApnsAuthorizationStatus() {
UNUserNotificationCenter.current().getNotificationSettings { settings in
if settings.authorizationStatus == .authorized {
nr_requestUploadApnsAuthorizationStatus(true)
} else if settings.authorizationStatus == .denied {
nr_requestUploadApnsAuthorizationStatus(false)
}
}
}
}

View File

@ -2,12 +2,13 @@
// NRStoreAPI.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/10.
// Created by on 2025/12/10.
//
import UIKit
import SmartCodable
import Alamofire
import JXIAPManager
struct NRStoreAPI {
@ -99,13 +100,17 @@ struct NRStoreAPI {
}
static func requestRechargeRecord(page: Int, buyType: BuyType, completer: ((_ listModel: NRNetwork.List<NROrderRecordsModel>?) -> Void)?) {
var type = "coins"
if buyType == .subVip {
type = "vip"
}
var param = NRNetwork.Parameters(path: "/getCustomerOrder")
param.method = .get
param.parameters = [
"page_size" : 20,
"current_page" : page,
"buy_type" : buyType.rawValue
"buy_type" : type
]
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRNetwork.List<NROrderRecordsModel>>) in
@ -175,4 +180,20 @@ struct NRStoreAPI {
}
}
///
static func requestCoinBagCanReceiveInfo() async -> NRCoinPackCanReceiveModel? {
await withCheckedContinuation { continuation in
var param = NRNetwork.Parameters(path: "/getReceiveDayCoin")
param.method = .get
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRCoinPackCanReceiveModel>) in
if response.isSuccess {
continuation.resume(returning: response.data)
} else {
continuation.resume(returning: nil)
}
}
}
}
}

View File

@ -2,7 +2,7 @@
// NRUserAPI.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRNetwork.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRNetworkModel.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRNetworkReachableManager.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRResponseCryptor.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRTargetType.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRUrlPath.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -0,0 +1,67 @@
//
// NRAppStartViewController.swift
// ReaderHive
//
// Created by on 2025/12/16.
//
import UIKit
import SnapKit
class NRAppStartViewController: NRViewController {
var openAppHandle: (() -> Void)?
private lazy var lanuchVC: UIViewController? = {
let vc = NRTool.lanuchViewController
return vc
}()
private lazy var startButton: UIButton = {
var configuration = UIButton.Configuration.plain()
configuration.background.image = UIImage(named: "gradient_color_01")
configuration.background.cornerRadius = 24
configuration.attributedTitle = AttributedString("Open".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .medium),
.foregroundColor : UIColor.white
]))
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
self?.openAppHandle?()
}))
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
if let vc = lanuchVC {
addChild(vc)
view.addSubview(vc.view)
}
nrPrint(message: UIScreen.safeBottom)
view.addSubview(startButton)
startButton.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.width.equalTo(150)
make.height.equalTo(48)
make.bottom.equalToSuperview().offset(-(UIScreen.safeBottom + 50))
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}

View File

@ -2,7 +2,7 @@
// NRNavigationController.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRTabBarController.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit
@ -40,6 +40,8 @@ class NRTabBarController: UITabBarController {
self.selectedIndex = 1
NRTool.checkUpdates()
NROpenAppManager.manager.requestIDFAAuthorization()
}

View File

@ -2,13 +2,14 @@
// NRViewController.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit
import SnapKit
import JXPagingView
import JXSegmentedView
import LYEmptyView
class NRViewController: UIViewController {
@ -21,6 +22,14 @@ class NRViewController: UIViewController {
return imageView
}()
private(set) lazy var notNetworkingEmptyView: LYEmptyView = {
let view = NREmpty.nr_emptyView(image: UIImage(named: "empty_image_02"), title: "not_networking_empty_text".localized, btnTitleStr: "Try again".localized, contentViewOffset: 0) { [weak self] in
self?.handleNotNetworkingEmptyBtn()
}
view.autoShowEmptyView = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
@ -51,6 +60,10 @@ class NRViewController: UIViewController {
completer?()
}
func handleNotNetworkingEmptyBtn() {
}
}
extension NRViewController: JXPagingSmoothViewListViewDelegate, JXPagingViewListViewDelegate, JXSegmentedListContainerViewListDelegate {
@ -67,10 +80,18 @@ extension NRViewController: JXPagingSmoothViewListViewDelegate, JXPagingViewList
return UIScrollView()
}
func listWillAppear() {
}
func listDidAppear() {
}
func listWillDisappear() {
}
func listDidDisappear() {
}

View File

@ -2,7 +2,7 @@
// NRCollectionView.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRGradientButton.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/5.
// Created by on 2025/12/5.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRGradientView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRImageView.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRLabel.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRPanModalContentView.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/28.
// Created by on 2025/11/28.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRProgressView.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/29.
// Created by on 2025/11/29.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRScrollView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRTableView.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRTableViewCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRAppWebViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/10.
// Created by on 2025/12/10.
//
import UIKit
@ -14,7 +14,7 @@ class NRAppWebViewController: NRWebViewController {
private var receiveDataCount = 0
var theme: String? = "theme_2"
var theme: String? = "theme_20"
override func viewDidLoad() {
super.viewDidLoad()

View File

@ -2,7 +2,7 @@
// NRWebView.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,12 +2,12 @@
// NRWebViewController+Script.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit
internal import WebKit
import ZLPhotoBrowser
import PhotosUI
///APP
let kNRWebMessageAPP = "js2app"
@ -75,25 +75,45 @@ extension NRWebViewController {
///
private func openPhotoPicker() {
var config = PHPickerConfiguration()
config.selectionLimit = 1
config.filter = .images
ZLPhotoConfiguration.default().allowSelectOriginal = false
ZLPhotoConfiguration.default().maxSelectCount = 1
ZLPhotoConfiguration.default().allowEditImage = false
ZLPhotoConfiguration.default().allowSelectVideo = false
ZLPhotoConfiguration.default().allowSelectGif = false
ZLPhotoConfiguration.default().allowTakePhotoInLibrary = false
let picker = ZLPhotoPicker()
picker.selectImageBlock = { [weak self] (results, _) in
guard let self = self else { return }
guard let image = results.first?.image else { return }
guard let imageData = image.jpegData(compressionQuality: 0.8) else { return }
let imageDataStr = imageData.base64EncodedString(options: .endLineWithCarriageReturn)
let js = "uploadConvertImage('\(imageDataStr)')"
self.webView.evaluateJavaScript(js)
}
picker.showPhotoLibrary(sender: self)
let picker = PHPickerViewController(configuration: config)
picker.delegate = self
self.present(picker, animated: true)
}
}
extension NRWebViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
guard let result = results.first else { return }
let provider = result.itemProvider
guard provider.canLoadObject(ofClass: UIImage.self) else { return }
provider.loadObject(ofClass: UIImage.self) { object, error in
guard let image = object as? UIImage else { return }
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.upload(image)
}
}
}
private func upload(_ image: UIImage) {
guard let imageData = image.jpegData(compressionQuality: 0.8) else { return }
let imageDataStr = imageData.base64EncodedString(options: .endLineWithCarriageReturn)
let js = "uploadConvertImage('\(imageDataStr)')"
self.webView.evaluateJavaScript(js)
}
}

View File

@ -2,7 +2,7 @@
// NRWebViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelMenuItem.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelContentListCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelGenresCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelMenuCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelMenuView.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRNovelGenresCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelContentListViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit
@ -41,11 +41,17 @@ class NRExploreNovelContentListViewController: NRViewController {
return collectionView
}()
@MainActor deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.backgroundImageView.isHidden = true
self.view.backgroundColor = .clear
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
nr_setupUI()
Task {
@ -54,7 +60,12 @@ class NRExploreNovelContentListViewController: NRViewController {
}
@objc private func networkStatusDidChangeNotification() {
guard NRNetworkReachableManager.manager.isReachable == true, self.dataArr.isEmpty else { return }
Task {
await requestDataArr()
}
}
}

View File

@ -2,7 +2,7 @@
// NRExploreNovelContentViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelGenresViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit
@ -42,11 +42,17 @@ class NRExploreNovelGenresViewController: NRViewController {
return collectionView
}()
@MainActor deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.backgroundImageView.isHidden = true
self.view.backgroundColor = .clear
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
nr_setupUI()
Task {
@ -54,7 +60,12 @@ class NRExploreNovelGenresViewController: NRViewController {
}
}
@objc private func networkStatusDidChangeNotification() {
guard NRNetworkReachableManager.manager.isReachable == true, self.dataArr.isEmpty else { return }
Task {
await requestDataArr()
}
}
}

View File

@ -2,7 +2,7 @@
// NRExploreNovelViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRNovelGenresViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelMenuDataSource.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRExploreNovelViewModel.swift
// ReaderHive
//
// Created by 鸿 on 2025/11/26.
// Created by on 2025/11/26.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelListViewController.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelNewViewController.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelViewController.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,11 +2,12 @@
// NRHomeViewController.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit
import SnapKit
import LYEmptyView
class NRHomeViewController: NRViewController {
@ -36,10 +37,20 @@ class NRHomeViewController: NRViewController {
return button
}()
@MainActor deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
nr_setupUI()
Task {
await requestCoinBagCanReceiveInfo()
}
}
override func viewWillAppear(_ animated: Bool) {
@ -47,12 +58,31 @@ class NRHomeViewController: NRViewController {
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func handleNotNetworkingEmptyBtn() {
self.nr_setupUI()
}
@objc private func networkStatusDidChangeNotification() {
guard NRNetworkReachableManager.manager.isReachable == true else { return }
nr_setupUI()
}
}
extension NRHomeViewController {
private func nr_setupUI() {
guard novelVC.view.superview == nil else { return }
if NRNetworkReachableManager.manager.isReachable != true {
if self.view.ly_emptyView == nil {
self.view.ly_emptyView = self.notNetworkingEmptyView
}
self.view.ly_showEmpty()
return;
}
self.view.ly_hideEmpty()
view.addSubview(searchButton)
view.addSubview(titleView)
addChild(novelVC)
@ -82,3 +112,22 @@ extension NRHomeViewController {
}
}
extension NRHomeViewController {
private func requestCoinBagCanReceiveInfo() async {
guard let model = await NRStoreAPI.requestCoinBagCanReceiveInfo() else { return }
let coins = model.coins ?? 0
guard coins > 0 else { return }
let view = NRCoinsPackAlert(model: model)
view.show(in: self.view)
view.highlightHandle = { [weak self] in
let vc = NRCoinsPackViewController()
self?.navigationController?.pushViewController(vc, animated: true)
}
}
}

View File

@ -2,7 +2,7 @@
// NRSearchViewController.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelModuleItem.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/2.
// Created by on 2025/12/2.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRReadWhatViewTransformer.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeCategoryTagView.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelHeaderContentView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelHeaderView.swift
// ReaderHive
//
// Created by on 2025/11/21.
// Created by on 2025/11/21.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelHotGridView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelHotTagCell.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelHotTagView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelListCell.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelListTextCell.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelMustReadTodayCell.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelMustReadTodayView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelNewArrivalsCell.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelNewArrivalsView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelNextView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelNextViewCell.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelReadWhatCell.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRHomeNovelReadWhatView.swift
// ReaderHive
//
// Created by on 2025/11/24.
// Created by on 2025/11/24.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRSearchHomeView.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRSearchInputView.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRSearchRecordCell.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRSearchRecordView.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRSearchResultCell.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRSearchResultView.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRStarGradeView.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/2.
// Created by on 2025/12/2.
//
import UIKit
@ -11,13 +11,15 @@ import Cosmos
class NRStarGradeView: UIView {
private let ratio: CGFloat = 2
//0-10
var grade: CGFloat {
set {
cosmosView.rating = newValue
cosmosView.rating = newValue / ratio
}
get {
return cosmosView.rating
return cosmosView.rating * ratio
}
}
@ -83,10 +85,12 @@ class NRStarGradeView: UIView {
private lazy var cosmosView: CosmosView = {
let view = CosmosView(settings: settings)
view.didTouchCosmos = { [weak self] rating in
self?.didTouch?(rating)
guard let self = self else { return }
self.didTouch?(rating * self.ratio)
}
view.didFinishTouchingCosmos = { [weak self] rating in
self?.didFinishTouching?(rating)
guard let self = self else { return }
self.didFinishTouching?(rating * self.ratio)
}
return view
}()

View File

@ -2,7 +2,7 @@
// NRHomeNovelViewModel.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/2.
// Created by on 2025/12/2.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRSearchViewModel.swift
// ReaderHive
//
// Created by on 2025/11/25.
// Created by on 2025/11/25.
//
import UIKit

View File

@ -0,0 +1,16 @@
//
// NRFeedbackCountModel.swift
// ReaderHive
//
// Created by on 2025/12/16.
//
import UIKit
import SmartCodable
class NRFeedbackCountModel: NSObject, SmartCodable {
required override init() { }
var feedback_notice_num: Int?
}

View File

@ -2,7 +2,7 @@
// NRLanguageModel.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/8.
// Created by on 2025/12/8.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRMeItem.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRAboutCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRAboutHeaderView.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRLanguageCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/8.
// Created by on 2025/12/8.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRMeCell.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/4.
// Created by on 2025/12/4.
//
import UIKit
@ -29,6 +29,12 @@ class NRMeCell: NRTableViewCell {
return label
}()
private(set) lazy var lineView: NRDashedLineView = {
let view = NRDashedLineView()
view.lineColor = .FFEFD_4
return view
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
@ -48,6 +54,7 @@ extension NRMeCell {
contentView.addSubview(iconImageView)
contentView.addSubview(titleLabel)
contentView.addSubview(nr_indicatorImageView)
contentView.addSubview(lineView)
iconImageView.snp.makeConstraints { make in
make.centerY.equalToSuperview()
@ -63,6 +70,12 @@ extension NRMeCell {
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-12)
}
lineView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.centerX.equalToSuperview()
make.bottom.equalToSuperview()
}
}
}

View File

@ -2,7 +2,7 @@
// NRMeCoinsContentView.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/8.
// Created by on 2025/12/8.
//
import UIKit

View File

@ -2,7 +2,7 @@
// NRMeCoinsPackView.swift
// ReaderHive
//
// Created by 鸿 on 2025/12/10.
// Created by on 2025/12/10.
//
import UIKit

Some files were not shown because too many files have changed in this diff Show More