@@ -5,31 +5,53 @@ import SwiftUI
55/// Service for handling app rating requests using StoreKit's native rating dialog
66public class RatingService {
77 public static let shared = RatingService ( )
8-
8+
9+ // These are placeholders for future “smart prompting” rules.
10+ // Kept for now to avoid a breaking change to any planned roadmap.
911 private let minimumLaunchCountForRating = 3
1012 private let minimumDaysSinceInstall = 7
1113 private let minimumDaysBetweenRatingRequests = 30
12-
14+
1315 private init ( ) { }
14-
16+
1517 /// Force request rating (useful for manual "Rate App" buttons)
1618 @MainActor
1719 public func requestRating( ) {
1820 guard let windowScene = UIApplication . shared. connectedScenes
1921 . first ( where: { $0. activationState == . foregroundActive } ) as? UIWindowScene else {
2022 return
2123 }
22-
24+
2325 SKStoreReviewController . requestReview ( in: windowScene)
2426 }
25-
26- /// Open App Store review page directly
27+
28+ /// Open App Store review page directly.
29+ ///
30+ /// - Parameter appId: The numeric App Store ID (e.g. "123456789").
2731 public func openAppStoreReview( appId: String ) {
28- let urlString = " https://apps.apple.com/app/id \( appId) ?action=write-review "
29- guard let url = URL ( string: urlString) else { return }
30-
31- if UIApplication . shared. canOpenURL ( url) {
32- UIApplication . shared. open ( url)
32+ let trimmed = appId. trimmingCharacters ( in: . whitespacesAndNewlines)
33+ guard !trimmed. isEmpty else { return }
34+ guard let url = URL ( string: " https://apps.apple.com/app/id \( trimmed) ?action=write-review " ) else { return }
35+
36+ UIApplication . shared. open ( url)
37+ }
38+
39+ /// Open App Store review page using an App Store URL (extracts the app id from the URL).
40+ ///
41+ /// If parsing fails, falls back to opening the provided URL.
42+ public func openAppStoreReview( appStoreURL: URL ) {
43+ let s = appStoreURL. absoluteString
44+
45+ // Typical formats include:
46+ // - https://apps.apple.com/us/app/some-app/id123456789
47+ // - https://apps.apple.com/app/id123456789
48+ if let match = s. range ( of: #"id(\d+)"# , options: . regularExpression) {
49+ let idPart = String ( s [ match] ) // e.g. "id123456789"
50+ let appId = idPart. replacingOccurrences ( of: " id " , with: " " )
51+ openAppStoreReview ( appId: appId)
52+ return
3353 }
54+
55+ UIApplication . shared. open ( appStoreURL)
3456 }
3557}
0 commit comments