Skip to content

Commit 5c0ec29

Browse files
committed
fix crashes
1 parent 64560c8 commit 5c0ec29

File tree

8 files changed

+59
-12
lines changed

8 files changed

+59
-12
lines changed

HabitRPG/Extensions/Down-Extensions.swift

+7-2
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,14 @@ extension Down {
9292
while range.length > 0 {
9393
string.replaceCharacters(in: range, with: "")
9494
let endRange = string.mutableString.range(of: "</strong>")
95-
string.replaceCharacters(in: endRange, with: "")
95+
if (endRange.isSafe(for: string)) {
96+
string.replaceCharacters(in: endRange, with: "")
97+
}
9698
let boldStart = range.location
97-
string.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: scaledBaseSize), range: NSRange(location: boldStart, length: endRange.location - boldStart))
99+
let boldRange = NSRange(location: boldStart, length: endRange.location - boldStart)
100+
if boldRange.isSafe(for: string) {
101+
string.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: scaledBaseSize), range: boldRange)
102+
}
98103

99104
range = string.mutableString.range(of: "<strong>")
100105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// NSRange-Extensions.swift
3+
// Habitica
4+
//
5+
// Created by Phillip Thelen on 15.01.25.
6+
// Copyright © 2025 HabitRPG Inc. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
extension NSRange {
12+
func isSafe(for str: NSString) -> Bool {
13+
return location != NSNotFound && location + length <= str.length
14+
}
15+
16+
func isSafe(for str: NSAttributedString) -> Bool {
17+
return location != NSNotFound && location + length <= str.length
18+
}
19+
}

HabitRPG/UI/General/ArmoireViewController.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ struct ArmoireView: View {
247247
ZStack {
248248
if !viewModel.isUsingPerk || viewModel.usedPerk {
249249
EmptyView()
250-
.confettiCannon(counter: $confettiCounter,
250+
.confettiCannon(trigger: $confettiCounter,
251251
num: 5,
252252
confettis: [.image(Asset.confettiPill.name)],
253253
colors: [Color(UIColor.yellow100), Color(UIColor.red100), Color(UIColor.blue100), Color(UIColor.purple400)], confettiSize: 10,

HabitRPG/UI/Inventory/ItemsViewController.swift

+12
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,27 @@ class ItemsViewController: BaseTableViewController {
5959
navigationItem.title = L10n.Titles.items
6060
}
6161

62+
private func requestReviewForHatching() {
63+
let defaults = UserDefaults.standard
64+
var fedCount = defaults.integer(forKey: "pet_hatch_count")
65+
fedCount += 1
66+
defaults.set(fedCount, forKey: "pet_hatch_count")
67+
if fedCount >= 2 {
68+
UIApplication.requestReview()
69+
}
70+
}
71+
6272
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
6373
let item = dataSource.item(at: indexPath)
6474
if isHatching {
6575
self.isHatching = false
6676
if let egg = dataSource.hatchingItem as? EggProtocol, let potion = item as? HatchingPotionProtocol {
6777
inventoryRepository.hatchPet(egg: egg, potion: potion).skipNil().observeValues { _ in
78+
self.requestReviewForHatching()
6879
}
6980
} else if let egg = item as? EggProtocol, let potion = dataSource.hatchingItem as? HatchingPotionProtocol {
7081
inventoryRepository.hatchPet(egg: egg, potion: potion).skipNil().observeValues { _ in
82+
self.requestReviewForHatching()
7183
}
7284
}
7385
} else if let item = item {

HabitRPG/UI/Inventory/Stable/PetDetailViewController.swift

+9-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,15 @@ class PetDetailViewController: StableDetailViewController<PetDetailDataSource> {
7272
@IBAction func unwindToFeed(_ segue: UIStoryboardSegue) {
7373
let feedViewController = segue.source as? FeedViewController
7474
if let pet = selectedPet, let food = feedViewController?.selectedFood {
75-
inventoryRepository.feed(pet: pet, food: food).observeCompleted {}
75+
inventoryRepository.feed(pet: pet, food: food).observeCompleted {
76+
let defaults = UserDefaults.standard
77+
var fedCount = defaults.integer(forKey: "pet_feed_count")
78+
fedCount += 1
79+
defaults.set(fedCount, forKey: "pet_feed_count")
80+
if fedCount >= 2 {
81+
UIApplication.requestReview()
82+
}
83+
}
7684
}
7785
}
7886

@@ -92,7 +100,6 @@ class PetDetailViewController: StableDetailViewController<PetDetailDataSource> {
92100
let equipString = L10n.equip
93101
actions.append(UIAction(title: equipString, handler: {[weak self] _ in
94102
self?.inventoryRepository.equip(type: "pet", key: stableItem.pet?.key ?? "").observeCompleted {
95-
UIApplication.requestReview()
96103
}
97104
}))
98105
}

HabitRPG/Views/ToastView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class ToastView: UIView {
179179

180180
var body: some View {
181181
EmptyView()
182-
.confettiCannon(counter: $counter,
182+
.confettiCannon(trigger: $counter,
183183
num: 5,
184184
confettis: [.image(Asset.subscriberStar.name)],
185185
colors: [Color(UIColor.yellow100)],

Habitica.xcodeproj/project.pbxproj

+8-4
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@
263263
29706CB727D911F5006EC139 /* XCUIApplication-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29706CB627D911F5006EC139 /* XCUIApplication-Extensions.swift */; };
264264
29706CB827D917CD006EC139 /* tasks.json in Resources */ = {isa = PBXBuildFile; fileRef = 29706CB427D9115C006EC139 /* tasks.json */; };
265265
2970CB52227B1A8600FACCB7 /* MarkdownTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2970CB51227B1A8600FACCB7 /* MarkdownTests.swift */; };
266+
29737EEF2D38055000480353 /* NSRange-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29737EEE2D38054C00480353 /* NSRange-Extensions.swift */; };
266267
2974BD91208DEFEA00EC1A25 /* CustomizationDetailCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2974BD90208DEFEA00EC1A25 /* CustomizationDetailCell.swift */; };
267268
2974BDAD208F68A800EC1A25 /* CustomizationHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2974BDAC208F68A800EC1A25 /* CustomizationHeaderView.swift */; };
268269
2974BDB42090926B00EC1A25 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2974BDB32090926B00EC1A25 /* MainTabBarController.swift */; };
@@ -931,6 +932,7 @@
931932
29706CB427D9115C006EC139 /* tasks.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = tasks.json; sourceTree = "<group>"; };
932933
29706CB627D911F5006EC139 /* XCUIApplication-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCUIApplication-Extensions.swift"; sourceTree = "<group>"; };
933934
2970CB51227B1A8600FACCB7 /* MarkdownTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownTests.swift; sourceTree = "<group>"; };
935+
29737EEE2D38054C00480353 /* NSRange-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSRange-Extensions.swift"; sourceTree = "<group>"; };
934936
2974BD90208DEFEA00EC1A25 /* CustomizationDetailCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomizationDetailCell.swift; sourceTree = "<group>"; };
935937
2974BDAC208F68A800EC1A25 /* CustomizationHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomizationHeaderView.swift; sourceTree = "<group>"; };
936938
2974BDB32090926B00EC1A25 /* MainTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = "<group>"; };
@@ -2210,12 +2212,16 @@
22102212
D95704371E106BF3004F6804 /* Extensions */ = {
22112213
isa = PBXGroup;
22122214
children = (
2215+
29737EEE2D38054C00480353 /* NSRange-Extensions.swift */,
2216+
29D50AD025F769520009CF55 /* Alignment-Extensions.swift */,
2217+
2909D42D2726ACBD00FF2B29 /* Binding-Extensions.swift */,
22132218
29255E4C1F3E25910094A3E3 /* CGRect-Extensions.swift */,
22142219
491C6E5A2020FE64005030A2 /* Challenge-Extensions.swift */,
22152220
29323E4820521FD500AC6D6F /* ContributorProtocol-Extensions.swift */,
22162221
29066CFE24FFA20B00A266EE /* Date-Extensions.swift */,
22172222
D9CE90461E4CDF3F00702578 /* Designable-Extensions.swift */,
22182223
D9BB45581E71AFAF0002AE2E /* Down-Extensions.swift */,
2224+
2959BC83275E1BDE005EE62D /* EditingFormViewController-Extensions.swift */,
22192225
D95704421E1528F2004F6804 /* Event-Extensions.swift */,
22202226
29A06E1C23ED4125003BADE9 /* InAppRewardProtocol-Extensions.swift */,
22212227
291448872088F3F700F3A6B5 /* NSAttributedString.swift */,
@@ -2227,9 +2233,9 @@
22272233
29A1B9B81F6ACC2F0055CF57 /* UIAlertAction-Extensions.swift */,
22282234
D96BFC4E1E191D7200266EEF /* UIAlertController-Extensions.swift */,
22292235
29701FDF1F560D310097BBCC /* UIApplication-Extensions.swift */,
2236+
29CEA821264150CA00101C0A /* UIColor-Contributor.swift */,
22302237
29ED1AFE1F339ACF005A3895 /* UIColor-Extensions.swift */,
22312238
291CE4B5231E828D0001A243 /* UIColor-Habitica.swift */,
2232-
29CEA821264150CA00101C0A /* UIColor-Contributor.swift */,
22332239
29A62B0A216CF4E200D4BD90 /* UIDevice-Extensions.swift */,
22342240
292AA72320FE15090022CC5F /* UIFont-Extensions.swift */,
22352241
293DFE3B24F5647400E115FE /* UIImage-Extensions.swift */,
@@ -2239,9 +2245,6 @@
22392245
29D16C8425A72211001D9A61 /* UITraitCollection-Extensions.swift */,
22402246
D9D17CCF1E673CCC00AD9232 /* UIView-Extensions.swift */,
22412247
29D50A6725F66F760009CF55 /* UIWindowScene-Extensions.swift */,
2242-
29D50AD025F769520009CF55 /* Alignment-Extensions.swift */,
2243-
2909D42D2726ACBD00FF2B29 /* Binding-Extensions.swift */,
2244-
2959BC83275E1BDE005EE62D /* EditingFormViewController-Extensions.swift */,
22452248
);
22462249
path = Extensions;
22472250
sourceTree = "<group>";
@@ -3573,6 +3576,7 @@
35733576
296E480821BE86F800D15E4A /* GiftSubscriptionViewController.swift in Sources */,
35743577
4904C7401F1ED87400F80723 /* GradientImageView.swift in Sources */,
35753578
2957B8CA1F4ED7C800E836EF /* Currency.swift in Sources */,
3579+
29737EEF2D38055000480353 /* NSRange-Extensions.swift in Sources */,
35763580
2974BDB62090C03E00EC1A25 /* InboxOverviewDataSource.swift in Sources */,
35773581
2959BC84275E1BDE005EE62D /* EditingFormViewController-Extensions.swift in Sources */,
35783582
29066CFB24FE83D300A266EE /* PromoBannerView.swift in Sources */,

Habitica.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
"location" : "https://github.com/simibac/ConfettiSwiftUI.git",
6262
"state" : {
6363
"branch" : "master",
64-
"revision" : "469de4e43949815dc92570cc786922d8d1385b06"
64+
"revision" : "d19c1705fdc8e4eca07f669b7350255602898fc8"
6565
}
6666
},
6767
{
@@ -268,7 +268,7 @@
268268
"location" : "https://github.com/ReactiveCocoa/ReactiveSwift",
269269
"state" : {
270270
"branch" : "master",
271-
"revision" : "83fb2959a4439440ce162c89384c3fae78d1b22e"
271+
"revision" : "8581f24e9944521975a1b2177a7bb9b95ab803ed"
272272
}
273273
},
274274
{

0 commit comments

Comments
 (0)