Skip to content

Commit 84572ba

Browse files
authored
Merge pull request #1140 from Esri/v.next
200.7 Release
2 parents 49a1b26 + c8d9f01 commit 84572ba

File tree

241 files changed

+16479
-1452
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

241 files changed

+16479
-1452
lines changed

Diff for: .swiftlint.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ opt_in_rules:
3333
- closure_end_indentation
3434
- closure_spacing
3535
- collection_alignment
36+
- contains_over_filter_count
37+
- contains_over_filter_is_empty
3638
- contains_over_first_not_nil
3739
- convenience_type
38-
- discouraged_direct_init
3940
- discouraged_optional_boolean
4041
- empty_count
4142
- empty_string
@@ -47,7 +48,6 @@ opt_in_rules:
4748
- function_default_parameter_at_end
4849
- identical_operands
4950
- joined_default_parameter
50-
- legacy_random
5151
- let_var_whitespace
5252
- literal_expression_end_indentation
5353
- lower_acl_than_parent
@@ -57,9 +57,9 @@ opt_in_rules:
5757
- multiline_function_chains
5858
- multiline_parameters
5959
- operator_usage_whitespace
60-
- operator_whitespace
6160
- overridden_super_call
6261
- override_in_extension
62+
- prefer_key_path
6363
- prohibited_super_call
6464
- redundant_nil_coalescing
6565
- redundant_type_annotation

Diff for: AuthenticationExample/AuthenticationExample.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@
353353
"$(inherited)",
354354
"@executable_path/Frameworks",
355355
);
356-
MARKETING_VERSION = 200.6.0;
356+
MARKETING_VERSION = 200.7.0;
357357
PRODUCT_BUNDLE_IDENTIFIER = com.esri.Authentication;
358358
PRODUCT_NAME = "$(TARGET_NAME)";
359359
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";
@@ -390,7 +390,7 @@
390390
"$(inherited)",
391391
"@executable_path/Frameworks",
392392
);
393-
MARKETING_VERSION = 200.6.0;
393+
MARKETING_VERSION = 200.7.0;
394394
PRODUCT_BUNDLE_IDENTIFIER = com.esri.Authentication;
395395
PRODUCT_NAME = "$(TARGET_NAME)";
396396
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";

Diff for: AuthenticationExample/AuthenticationExample/LoadableImageView.swift

+49-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2022 Esri
1+
// Copyright 2024 Esri
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -17,32 +17,68 @@ import SwiftUI
1717

1818
/// A view that loads a `LoadableImage` and displays it.
1919
/// While the image is loading a progress view is displayed.
20-
/// If there is an error displaying the image a red exclamation circle is displayed.
21-
struct LoadableImageView: View {
20+
/// If there is an error loading the image then user defined failure content is shown.
21+
/// Once the image loads, a user-defined closure is used to display the image.
22+
struct LoadableImageView<FailureContent: View, LoadedContent: View>: View {
2223
/// The loadable image to display.
2324
let loadableImage: LoadableImage
24-
25+
/// The content to display in the case of load failure.
26+
var failureContent: (() -> FailureContent)?
27+
/// The content to display once the image loads.
28+
var loadedContent: (Image) -> LoadedContent
2529
/// The result of loading the image.
26-
@State private var result: Result<UIImage, Error>?
30+
@State var result: Result<UIImage, Error>?
31+
32+
/// Creates a `LoadableImageView`.
33+
/// - Parameters:
34+
/// - loadableImage: The loadable image.
35+
/// - failureContent: The content to display if the loadable image fails to load.
36+
/// - loadedContent: The content to display once the loadable image loads.
37+
init(
38+
loadableImage: LoadableImage,
39+
failureContent: @escaping () -> FailureContent,
40+
loadedContent: @escaping (Image) -> LoadedContent
41+
) {
42+
self.loadableImage = loadableImage
43+
self.failureContent = failureContent
44+
self.loadedContent = loadedContent
45+
}
46+
47+
/// Creates a `LoadableImageView`.
48+
/// - Parameters:
49+
/// - loadableImage: The loadable image.
50+
/// - loadedContent: The content to display once the loadable image loads.
51+
init(
52+
loadableImage: LoadableImage,
53+
loadedContent: @escaping (Image) -> LoadedContent
54+
) where FailureContent == EmptyView {
55+
self.loadableImage = loadableImage
56+
self.failureContent = nil
57+
self.loadedContent = loadedContent
58+
}
59+
60+
/// An error to signify that the loadable image had a null image once it loaded.
61+
/// This shouldn't ever happen, but in the case that it does, the failure content
62+
/// will be displayed.
63+
private struct NoImageError: Error {}
2764

2865
var body: some View {
2966
Group {
3067
switch result {
3168
case .none:
3269
ProgressView()
3370
case .failure:
34-
Image(systemName: "exclamationmark.circle")
35-
.aspectRatio(contentMode: .fit)
36-
.foregroundColor(.red)
71+
if let failureContent {
72+
failureContent()
73+
}
3774
case .success(let image):
38-
Image(uiImage: image)
39-
.resizable()
75+
loadedContent(Image(uiImage: image))
4076
}
41-
}
42-
.task {
77+
}.task {
4378
result = await Result {
4479
try await loadableImage.load()
45-
return loadableImage.image ?? UIImage()
80+
guard let image = loadableImage.image else { throw NoImageError() }
81+
return image
4682
}
4783
}
4884
}

Diff for: AuthenticationExample/AuthenticationExample/MapItemView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct MapItemView: View {
3434
case .failure(let error):
3535
Text(error.localizedDescription)
3636
.font(.footnote)
37-
.foregroundColor(.secondary)
37+
.foregroundStyle(.secondary)
3838
}
3939
}
4040
.task {

Diff for: AuthenticationExample/AuthenticationExample/SignInView.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ struct SignInView: View {
4848
#else
4949
.font(.footnote)
5050
#endif
51-
.foregroundColor(.secondary)
51+
.foregroundStyle(.secondary)
5252
signInButton
5353
}
5454
Spacer()
5555
if let error = error, !error.isChallengeCancellationError {
5656
Text(error.localizedDescription)
5757
.font(.footnote)
58-
.foregroundColor(.secondary)
58+
.foregroundStyle(.secondary)
5959
}
6060
}
6161
.task {

Diff for: AuthenticationExample/AuthenticationExample/UserView.swift

+16-8
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ struct UserView: View {
2424
VStack {
2525
Group {
2626
if let thumbnail = user.thumbnail {
27-
LoadableImageView(loadableImage: thumbnail)
28-
.frame(width: 100, height: 100, alignment: .center)
29-
.clipShape(Circle())
27+
LoadableImageView(loadableImage: thumbnail) {
28+
placeholderImage
29+
} loadedContent: { image in
30+
image
31+
.frame(width: 100, height: 100, alignment: .center)
32+
.clipShape(Circle())
33+
}
3034
} else {
31-
Image(systemName: "person.circle")
32-
.resizable()
33-
.foregroundColor(.secondary)
35+
placeholderImage
3436
}
3537
}
3638
.frame(width: 100, height: 100, alignment: .center)
@@ -63,6 +65,12 @@ struct UserView: View {
6365
}
6466
}
6567
}
68+
69+
@ViewBuilder private var placeholderImage: some View {
70+
Image(systemName: "person.circle")
71+
.resizable()
72+
.foregroundColor(.secondary)
73+
}
6674
}
6775

6876
extension PortalUser.Role: @retroactive CustomStringConvertible {
@@ -92,7 +100,7 @@ struct UserAttributeView: View {
92100
VStack(alignment: .leading, spacing: 2) {
93101
Text(title)
94102
.lineLimit(1)
95-
.foregroundColor(.secondary)
103+
.foregroundStyle(.secondary)
96104
.font(.footnote)
97105
Text(detail)
98106
.font(.caption)
@@ -113,7 +121,7 @@ struct UserAttributeListView: View {
113121
VStack(alignment: .leading, spacing: 2) {
114122
Text(title)
115123
.lineLimit(1)
116-
.foregroundColor(.secondary)
124+
.foregroundStyle(.secondary)
117125
.font(.footnote)
118126
Text(details.map(\.description).joined(separator: "\r"))
119127
.font(.caption)

Diff for: AuthenticationExample/AuthenticationExample/WebMapsView.swift

+6-3
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@ struct PortalItemView: View {
6969
var body: some View {
7070
HStack {
7171
if let thumbnail = item.thumbnail {
72-
LoadableImageView(loadableImage: thumbnail)
73-
.frame(width: 64, height: 44)
72+
LoadableImageView(loadableImage: thumbnail) { image in
73+
image
74+
.resizable()
75+
.frame(width: 64, height: 44)
76+
}
7477
}
7578
VStack(alignment: .leading, spacing: 2) {
7679
Text(item.title)
@@ -80,7 +83,7 @@ struct PortalItemView: View {
8083
.font(.caption)
8184
Text(item.snippet)
8285
.font(.caption)
83-
.foregroundColor(.secondary)
86+
.foregroundStyle(.secondary)
8487
.lineLimit(2)
8588
}
8689
}

0 commit comments

Comments
 (0)