From bd38bd769a20ebe89cec75ebc80dcbccfbd25230 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Sun, 5 Nov 2023 15:02:39 -0800 Subject: [PATCH] Improve ContactList layout and improve subtitle line breaking (#18) # Improve ContactList layout and improve subtitle line breaking ## :recycle: Current situation & Problem Currently, the `ContactsList` view is built using a custom ScrollView implementation and drawing custom backgrounds with shades around the `ContactView`s. This doesn't really feel native on iOS. Instead, this PR rethinks the implementation by rebuilding the `ContactsList` view using SwiftUI standard components like `List`. This makes the `ContactsList` now feel right at home. Further, previously the subtitle, consisting of the Person's title and organization, was built using multiple distinct `Text` instances. This caused problems when the text was longer than the view was capable of displaying. This PR ensures that a persons title and organization are combined into a single `Text` view and allows to to wrap into a second line. Lastly, this PR migrates the PR to use String catalogs, optimizes key naming and bumps the target to iOS 17. Below are two screenshots comparing the previous implementation to the updated one. Bildschirmfoto 2023-11-01 um 22 13 11 Bildschirmfoto 2023-11-01 um 22 12 14 ## :gear: Release Notes * New updated visuals for the `ContactsView` that feel way more native to iOS * Updated line breaking behavior for too long contact subtitles (title and organization) * Migrated to use String Catalogs for localization ## :books: Documentation -- ## :white_check_mark: Testing Tests were slightly adjusted, due to issues with line breaks in the labels. ## :pencil: Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md). --- Package.swift | 9 +- .../Contact Views/ContactCard.swift | 41 ---- .../Contact Views/ContactView.swift | 51 +++-- .../Contact Views/ContactsList.swift | 13 +- Sources/SpeziContact/Models/Contact.swift | 6 +- .../SpeziContact/Models/ContactOption.swift | 24 ++- .../Resources/Localizable.xcstrings | 193 ++++++++++++++++++ .../Resources/Localizable.xcstrings.license | 5 + .../Resources/de.lproj/Localizable.strings | 22 -- .../Resources/en.lproj/Localizable.strings | 22 -- .../TestAppUITests/SpeziContactsTests.swift | 6 +- .../UITests/UITests.xcodeproj/project.pbxproj | 6 +- 12 files changed, 264 insertions(+), 134 deletions(-) delete mode 100644 Sources/SpeziContact/Contact Views/ContactCard.swift create mode 100644 Sources/SpeziContact/Resources/Localizable.xcstrings create mode 100644 Sources/SpeziContact/Resources/Localizable.xcstrings.license delete mode 100644 Sources/SpeziContact/Resources/de.lproj/Localizable.strings delete mode 100644 Sources/SpeziContact/Resources/en.lproj/Localizable.strings diff --git a/Package.swift b/Package.swift index b0f5bf6..a9c5f4d 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.9 // // This source file is part of the Stanford Spezi open-source project @@ -15,19 +15,20 @@ let package = Package( name: "SpeziContact", defaultLocalization: "en", platforms: [ - .iOS(.v16) + .iOS(.v17) ], products: [ .library(name: "SpeziContact", targets: ["SpeziContact"]) ], dependencies: [ - .package(url: "https://github.com/StanfordSpezi/SpeziViews", .upToNextMinor(from: "0.5.0")) + .package(url: "https://github.com/StanfordSpezi/SpeziViews", .upToNextMinor(from: "0.6.0")) ], targets: [ .target( name: "SpeziContact", dependencies: [ - .product(name: "SpeziViews", package: "SpeziViews") + .product(name: "SpeziViews", package: "SpeziViews"), + .product(name: "SpeziPersonalInfo", package: "SpeziViews") ] ), .testTarget( diff --git a/Sources/SpeziContact/Contact Views/ContactCard.swift b/Sources/SpeziContact/Contact Views/ContactCard.swift deleted file mode 100644 index db162d3..0000000 --- a/Sources/SpeziContact/Contact Views/ContactCard.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// This source file is part of the Stanford Spezi open-source project -// -// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) -// -// SPDX-License-Identifier: MIT -// - - -import SwiftUI - - -struct ContactCard: View { - private let contact: Contact - - - var body: some View { - ContactView(contact: contact) - .padding() - .background { - RoundedRectangle(cornerRadius: 10) - .foregroundStyle(.background) - .shadow(radius: 5) - } - } - - - init(contact: Contact) { - self.contact = contact - } -} - - -#if DEBUG -struct ContactCard_Previews: PreviewProvider { - static var previews: some View { - ContactCard(contact: ContactView_Previews.mock) - .padding() - } -} -#endif diff --git a/Sources/SpeziContact/Contact Views/ContactView.swift b/Sources/SpeziContact/Contact Views/ContactView.swift index ecc982d..5ca814e 100644 --- a/Sources/SpeziContact/Contact Views/ContactView.swift +++ b/Sources/SpeziContact/Contact Views/ContactView.swift @@ -8,6 +8,7 @@ import Contacts import MessageUI +import SpeziPersonalInfo import SpeziViews import SwiftUI @@ -26,7 +27,21 @@ public struct ContactView: View { return (contact.contactOptions.dropLast(leftOverElements), contact.contactOptions.dropFirst(columnCount * numberOfRows)) } - private var subtitleLabel: Text { + private var subtitleText: Text { + var text = Text(verbatim: "") + if let title = contact.title { + text = text + Text(verbatim: title) // swiftlint:disable:this shorthand_operator + } + if contact.title != nil && contact.organization != nil { + text = text + Text(verbatim: " - ") // swiftlint:disable:this shorthand_operator + } + if let organization = contact.organization { + text = text + Text(verbatim: organization) // swiftlint:disable:this shorthand_operator + } + return text + } + + private var subtitleAccessibilityLabel: Text { var text: Text? if let title = contact.title { text = Text(verbatim: title) @@ -34,7 +49,7 @@ public struct ContactView: View { if let organization = contact.organization { if let titleText = text { - text = titleText + Text(" ") + Text("TITLE_AT_ORG", bundle: .module) + Text(" ") + Text(verbatim: organization) + text = titleText + Text(" at \(organization)", bundle: .module, comment: "Accessibility label: ' at '") } else { text = Text(verbatim: organization) } @@ -42,13 +57,13 @@ public struct ContactView: View { return text ?? Text(verbatim: "") } - + public var body: some View { VStack { header Divider() if let description = contact.description { - Label(description, textStyle: .subheadline) + Label(verbatim: description, textStyle: .subheadline) .padding(.vertical, 4) } HorizontalGeometryReader { _ in @@ -60,7 +75,7 @@ public struct ContactView: View { addressButton } } - + private var header: some View { HStack(spacing: 0) { UserProfileView(name: contact.name) { @@ -74,25 +89,19 @@ public struct ContactView: View { let name = contact.name.formatted(.name(style: .long)) Text(verbatim: name) .font(.title3.bold()) - .accessibilityLabel(Text("CONTACT \(name)", bundle: .module)) + .accessibilityLabel(Text("Contact: \(name)", bundle: .module, comment: "Accessibility Label")) .accessibilityAddTraits(.isHeader) if contact.title != nil || contact.organization != nil { HStack(spacing: 0) { - if let title = contact.title { - Text(verbatim: title) - } - if contact.title != nil && contact.organization != nil { - Text(" - ") - } - if let organization = contact.organization { - Text(verbatim: organization) - } + subtitleText + .lineLimit(1...2) + .fixedSize(horizontal: false, vertical: true) } .foregroundColor(Color(.secondaryLabel)) .font(.subheadline) .accessibilityRepresentation { - subtitleLabel + subtitleAccessibilityLabel } } } @@ -104,7 +113,7 @@ public struct ContactView: View { private var contactSection: some View { VStack(spacing: 8) { LazyVGrid( - columns: [GridItem(.adaptive(minimum: 100))], + columns: [GridItem(.adaptive(minimum: 95))], alignment: .center, spacing: 8 ) { @@ -135,7 +144,7 @@ public struct ContactView: View { .foregroundStyle(Color(uiColor: .secondarySystemBackground)) HStack(alignment: .top) { VStack(alignment: .leading, spacing: 4) { - Text("CONTACT_ADDRESS", bundle: .module) + Text("Address", bundle: .module, comment: "Contact Button Title") .foregroundColor(.accentColor) Text(verbatim: CNPostalAddressFormatter().string(from: address)) .multilineTextAlignment(.leading) @@ -151,7 +160,11 @@ public struct ContactView: View { } .fixedSize(horizontal: false, vertical: true) } - .accessibilityLabel(Text("ADDRESS_NAVIGATE \(Text(verbatim: CNPostalAddressFormatter().string(from: address)))", bundle: .module)) + .accessibilityLabel(Text( + "Address: \(Text(verbatim: CNPostalAddressFormatter().string(from: address)))", + bundle: .module, + comment: "Accessibility Label" + )) } else { EmptyView() } diff --git a/Sources/SpeziContact/Contact Views/ContactsList.swift b/Sources/SpeziContact/Contact Views/ContactsList.swift index f627e18..b079964 100644 --- a/Sources/SpeziContact/Contact Views/ContactsList.swift +++ b/Sources/SpeziContact/Contact Views/ContactsList.swift @@ -22,15 +22,14 @@ public struct ContactsList: View { public var body: some View { - ScrollView(.vertical) { + List { ForEach(contacts, id: \.id) { contact in - ContactCard(contact: contact) - .padding(.horizontal) - .padding(.vertical, 6) + Section { + ContactView(contact: contact) + .buttonStyle(.plain) // ensure the whole list row doesn't render as a button + } } - .padding(.vertical, 6) } - .background(Color(.systemGroupedBackground)) } @@ -53,7 +52,7 @@ struct ContactsList_Previews: PreviewProvider { ContactView_Previews.mock ] ) - .navigationTitle("Contacts") + .navigationTitle(Text(verbatim: "Contacts")) .background(Color(.systemGroupedBackground)) } } diff --git a/Sources/SpeziContact/Models/Contact.swift b/Sources/SpeziContact/Models/Contact.swift index 3af8172..71763d0 100644 --- a/Sources/SpeziContact/Models/Contact.swift +++ b/Sources/SpeziContact/Models/Contact.swift @@ -19,7 +19,7 @@ public struct Contact { public let image: Image? /// The title of the individual. public let title: String? - /// The desciption of the individual. + /// The description of the individual. public let description: String? /// The organization of the individual. public let organization: String? @@ -30,11 +30,11 @@ public struct Contact { /// - Parameters: - /// - id: Identiifer of the `Contact` instance. + /// - id: Identifier of the `Contact` instance. /// - name: The name of the individual. Ideally provide at least a first and given name. /// - image: The image of the ``Contact``. /// - title: The title of the individual. - /// - description: The desciption of the individual. + /// - description: The description of the individual. /// - organization: The organization of the individual. /// - address: The address of the individual. /// - contactOptions: The contact options of the individual. diff --git a/Sources/SpeziContact/Models/ContactOption.swift b/Sources/SpeziContact/Models/ContactOption.swift index 5656b74..6f61322 100644 --- a/Sources/SpeziContact/Models/ContactOption.swift +++ b/Sources/SpeziContact/Models/ContactOption.swift @@ -51,12 +51,12 @@ extension ContactOption { public static func call(_ number: String) -> ContactOption { ContactOption( image: Image(systemName: "phone.fill"), - title: String(localized: "CONTACT_OPTION_CALL", bundle: .module) + title: String(localized: "Call", bundle: .module, comment: "Contact Option") ) { guard let url = URL(string: "tel://\(number)"), UIApplication.shared.canOpenURL(url) else { presentAlert( - title: String(localized: "CONTACT_OPTION_CALL", bundle: .module), - message: String(localized: "CONTACT_OPTION_CALL_MANUAL \(number)", bundle: .module) + title: String(localized: "Call", bundle: .module), + message: String(localized: "Call unavailable. You can manually reach out to \(number)", bundle: .module, comment: "Call unavailable. Manual approach.") ) return } @@ -69,12 +69,12 @@ extension ContactOption { public static func text(_ number: String) -> ContactOption { ContactOption( image: Image(systemName: "message.fill"), - title: String(localized: "CONTACT_OPTION_TEXT", bundle: .module) + title: String(localized: "Text", bundle: .module, comment: "Contact Option") ) { guard let url = URL(string: "sms:\(number)"), UIApplication.shared.canOpenURL(url) else { presentAlert( - title: String(localized: "CONTACT_OPTION_TEXT", bundle: .module), - message: String(localized: "CONTACT_OPTION_TEXT_MANUAL \(number)", bundle: .module) + title: String(localized: "Text", bundle: .module), + message: String(localized: "Text unavailable. You can manually reach out to \(number)", bundle: .module, comment: "Text unavailable. Manual approach.") ) return } @@ -90,13 +90,17 @@ extension ContactOption { public static func email(addresses: [String], subject: String? = nil) -> ContactOption { ContactOption( image: Image(systemName: "envelope.fill"), - title: String(localized: "CONTACT_OPTION_EMAIL", bundle: .module) + title: String(localized: "Email", bundle: .module, comment: "Contact Option") ) { guard let subject = (subject ?? "").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: "mailto:\(addresses.joined(separator: ";"))?subject=\(subject)"), UIApplication.shared.canOpenURL(url) else { presentAlert( - title: String(localized: "CONTACT_OPTION_EMAIL", bundle: .module), - message: String(localized: "CONTACT_OPTION_EMAIL_MANUAL \(addresses.joined(separator: ", "))", bundle: .module) + title: String(localized: "Email", bundle: .module), + message: String( + localized: "Email unavailable. You can manually reach out to \(addresses.joined(separator: ", "))", + bundle: .module, + comment: "Email unavailable. Manual approach." + ) ) return } @@ -106,7 +110,7 @@ extension ContactOption { private static func presentAlert(title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: String(localized: "CONTACT_MANUAL_DISMISS", bundle: .module), style: .default)) + alert.addAction(UIAlertAction(title: String(localized: "Ok", bundle: .module, comment: "Dismiss alert"), style: .default)) rootViewController?.present(alert, animated: true, completion: nil) } } diff --git a/Sources/SpeziContact/Resources/Localizable.xcstrings b/Sources/SpeziContact/Resources/Localizable.xcstrings new file mode 100644 index 0000000..4cae2e2 --- /dev/null +++ b/Sources/SpeziContact/Resources/Localizable.xcstrings @@ -0,0 +1,193 @@ +{ + "sourceLanguage" : "en", + "strings" : { + " at %@" : { + "comment" : "Accessibility label: ' at '", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : " bei %@" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : " at %@" + } + } + } + }, + "Address" : { + "comment" : "Contact Button Title", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Adresse" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Address" + } + } + } + }, + "Address: %@" : { + "comment" : "Accessibility Label", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Adresse: %@" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Address: %@" + } + } + } + }, + "Call" : { + "comment" : "Contact Option", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Anrufen" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Call" + } + } + } + }, + "Call unavailable. You can manually reach out to %@" : { + "comment" : "Call unavailable. Manual approach.", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Das Gerät kann keinen Anruf tätigen. Sie können %@ anderweitig erreichen." + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The device is not setup to make a call. You can manually reach out to %@." + } + } + } + }, + "Contact: %@" : { + "comment" : "Accessibility Label", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kontakt: %@" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Contact: %@" + } + } + } + }, + "Email" : { + "comment" : "Contact Option", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "E-Mail" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Email" + } + } + } + }, + "Email unavailable. You can manually reach out to %@" : { + "comment" : "Email unavailable. Manual approach.", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Das Gerät kann keine E-Mail senden. Sie können %@ anderweitig erreichen." + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The device is not setup to send email. You can manually reach out to %@." + } + } + } + }, + "Ok" : { + "comment" : "Dismiss alert", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ok" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ok" + } + } + } + }, + "Text" : { + "comment" : "Contact Option", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nachricht" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Text" + } + } + } + }, + "Text unavailable. You can manually reach out to %@" : { + "comment" : "Text unavailable. Manual approach.", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Das Gerät kann keine Nachriten senden. Sie können %@ anderweitig erreichen." + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The device is not setup to send a text. You can manually reach out to %@." + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Sources/SpeziContact/Resources/Localizable.xcstrings.license b/Sources/SpeziContact/Resources/Localizable.xcstrings.license new file mode 100644 index 0000000..a3bb08d --- /dev/null +++ b/Sources/SpeziContact/Resources/Localizable.xcstrings.license @@ -0,0 +1,5 @@ +This source file is part of the Stanford Spezi open-source project + +SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT \ No newline at end of file diff --git a/Sources/SpeziContact/Resources/de.lproj/Localizable.strings b/Sources/SpeziContact/Resources/de.lproj/Localizable.strings deleted file mode 100644 index 7a6fca9..0000000 --- a/Sources/SpeziContact/Resources/de.lproj/Localizable.strings +++ /dev/null @@ -1,22 +0,0 @@ -// -// This source file is part of the Stanford Spezi open-source project -// -// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) -// -// SPDX-License-Identifier: MIT -// - -// MARK: - Contact Options -"CONTACT_OPTION_CALL" = "Anrufen"; -"CONTACT_OPTION_CALL_MANUAL %@" = "Das Gerät kann keinen Anruf tätigen. Sie können %@ anderweitig erreichen."; -"CONTACT_OPTION_TEXT" = "Nachricht"; -"CONTACT_OPTION_TEST_MANUAL %@" = "Das Gerät kann keine SMS senden. Sie können %@ anderweitig erreichen."; -"CONTACT_OPTION_EMAIL" = "E-Mail"; -"CONTACT_OPTION_EMAIL_MANUAL %@" = "Das Gerät kann keine E-Mail senden. Sie können %@ anderweitig erreichen."; -"CONTACT_MANUAL_DISMISS" = "Ok"; - -"CONTACT_ADDRESS" = "Adresse"; - -"CONTACT %@" = "Kontakt: %@"; -"TITLE_AT_ORG" = "bei"; -"ADDRESS_NAVIGATE %@" = "Navigiere zur Address: %@"; diff --git a/Sources/SpeziContact/Resources/en.lproj/Localizable.strings b/Sources/SpeziContact/Resources/en.lproj/Localizable.strings deleted file mode 100644 index c456eb2..0000000 --- a/Sources/SpeziContact/Resources/en.lproj/Localizable.strings +++ /dev/null @@ -1,22 +0,0 @@ -// -// This source file is part of the Stanford Spezi open-source project -// -// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) -// -// SPDX-License-Identifier: MIT -// - -// MARK: - Contact Options -"CONTACT_OPTION_CALL" = "Call"; -"CONTACT_OPTION_CALL_MANUAL %@" = "The device is not setup to make a call. You can manually reach out to %@."; -"CONTACT_OPTION_TEXT" = "Text"; -"CONTACT_OPTION_TEXT_MANUAL %@" = "The device is not setup to send a text. You can manually reach out to %@."; -"CONTACT_OPTION_EMAIL" = "Email"; -"CONTACT_OPTION_EMAIL_MANUAL %@" = "The device is not setup to send email. You can manually reach out to %@."; -"CONTACT_MANUAL_DISMISS" = "Ok"; - -"CONTACT_ADDRESS" = "Address"; - -"CONTACT %@" = "Contact: %@"; -"TITLE_AT_ORG" = "at"; -"ADDRESS_NAVIGATE %@" = "Navigate to Address: %@"; diff --git a/Tests/UITests/TestAppUITests/SpeziContactsTests.swift b/Tests/UITests/TestAppUITests/SpeziContactsTests.swift index 17f250f..277efd2 100644 --- a/Tests/UITests/TestAppUITests/SpeziContactsTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziContactsTests.swift @@ -45,9 +45,9 @@ final class ContactsTests: XCTestCase { XCTAssertEqual(app.buttons.matching(identifier: "Cloud").count, 2) app.buttons.matching(identifier: "Cloud").element(boundBy: 0).tap() - let address = "Navigate to Address: 450 Serra Mall\nStanford CA 94305\nUSA" - XCTAssertEqual(app.buttons.matching(identifier: address).count, 2) - app.buttons.matching(identifier: address).element(boundBy: 0).tap() + let predicate = NSPredicate(format: "label BEGINSWITH 'Address: 450 Serra Mall'") + XCTAssertEqual(app.buttons.matching(predicate).count, 2) + app.buttons.matching(predicate).element(boundBy: 0).tap() let maps = XCUIApplication(bundleIdentifier: "com.apple.Maps") XCTAssert(maps.wait(for: .runningForeground, timeout: 2)) } diff --git a/Tests/UITests/UITests.xcodeproj/project.pbxproj b/Tests/UITests/UITests.xcodeproj/project.pbxproj index 88fd626..21699fb 100644 --- a/Tests/UITests/UITests.xcodeproj/project.pbxproj +++ b/Tests/UITests/UITests.xcodeproj/project.pbxproj @@ -280,7 +280,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -334,7 +334,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -494,7 +494,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES;