From 48a2d883845f7cc94c5b3047c220d69cbfcb1247 Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Fri, 23 Jun 2023 00:33:44 -0700 Subject: [PATCH 1/3] Fix Email and Text Message issues and support iOS 17 --- .../Contact Views/ContactCard.swift | 12 +- .../Contact Views/ContactView.swift | 20 +++- .../SpeziContact/Models/ContactOption.swift | 23 ++-- Tests/UITests/TestApp.xctestplan | 9 ++ .../xcshareddata/xcschemes/TestApp.xcscheme | 104 ++++++++++++++++++ 5 files changed, 144 insertions(+), 24 deletions(-) create mode 100644 Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme diff --git a/Sources/SpeziContact/Contact Views/ContactCard.swift b/Sources/SpeziContact/Contact Views/ContactCard.swift index 904c698..e074738 100644 --- a/Sources/SpeziContact/Contact Views/ContactCard.swift +++ b/Sources/SpeziContact/Contact Views/ContactCard.swift @@ -18,9 +18,15 @@ struct ContactCard: View { ContactView(contact: contact) .padding() .background { - RoundedRectangle(cornerRadius: 10) - .foregroundColor(Color(.systemBackground)) - .shadow(radius: 5) + if #available(iOS 17.0, *) { + RoundedRectangle(cornerRadius: 10) + .foregroundStyle(.background) + .shadow(radius: 5) + } else { + RoundedRectangle(cornerRadius: 10) + .foregroundColor(Color(.systemBackground)) + .shadow(radius: 5) + } } } diff --git a/Sources/SpeziContact/Contact Views/ContactView.swift b/Sources/SpeziContact/Contact Views/ContactView.swift index 15d2f65..8c9a928 100644 --- a/Sources/SpeziContact/Contact Views/ContactView.swift +++ b/Sources/SpeziContact/Contact Views/ContactView.swift @@ -21,7 +21,7 @@ public struct ContactView: View { private var contactOptions: (grid: some RandomAccessCollection, leftOverStack: some RandomAccessCollection) { - let columnCount = Int(contactGridWidth / contentElementWidth) + let columnCount = max(Int(contactGridWidth / max(contentElementWidth, 64)), 1) let (numberOfRows, leftOverElements) = contact.contactOptions.count.quotientAndRemainder(dividingBy: columnCount) return (contact.contactOptions.dropLast(leftOverElements), contact.contactOptions.dropFirst(columnCount * numberOfRows)) } @@ -105,8 +105,13 @@ public struct ContactView: View { if let address = contact.address { Button(action: openMaps) { ZStack { - RoundedRectangle(cornerRadius: 10.0) - .foregroundColor(Color(.systemGroupedBackground)) + if #available(iOS 17.0, *) { + RoundedRectangle(cornerRadius: 10) + .foregroundStyle(.background.secondary) + } else { + RoundedRectangle(cornerRadius: 10) + .foregroundColor(Color(.systemGroupedBackground)) + } HStack(alignment: .top) { VStack(alignment: .leading, spacing: 4) { Text("CONTACT_ADDRESS", bundle: .module) @@ -140,8 +145,13 @@ public struct ContactView: View { private func contactButton(_ contactOption: ContactOption) -> some View { Button(action: contactOption.action) { ZStack { - RoundedRectangle(cornerRadius: 10.0) - .foregroundColor(Color(.systemGroupedBackground)) + if #available(iOS 17.0, *) { + RoundedRectangle(cornerRadius: 10) + .foregroundStyle(.background.secondary) + } else { + RoundedRectangle(cornerRadius: 10) + .foregroundColor(Color(.systemGroupedBackground)) + } VStack(spacing: 8) { contactOption.image .font(.title3) diff --git a/Sources/SpeziContact/Models/ContactOption.swift b/Sources/SpeziContact/Models/ContactOption.swift index aaf5e4d..fa74294 100644 --- a/Sources/SpeziContact/Models/ContactOption.swift +++ b/Sources/SpeziContact/Models/ContactOption.swift @@ -34,6 +34,8 @@ public struct ContactOption { } extension ContactOption { + private static var delegateReference: NSObject? + private static var rootViewController: UIViewController? { UIApplication .shared @@ -69,19 +71,14 @@ extension ContactOption { image: Image(systemName: "message.fill"), title: String(localized: "CONTACT_OPTION_TEXT", bundle: .module) ) { - guard MFMessageComposeViewController.canSendText() else { + 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) ) return } - - let controller = MFMessageComposeViewController() - - controller.recipients = [number] - - rootViewController?.present(controller, animated: true, completion: nil) + UIApplication.shared.open(url) } } @@ -95,21 +92,15 @@ extension ContactOption { image: Image(systemName: "envelope.fill"), title: String(localized: "CONTACT_OPTION_EMAIL", bundle: .module) ) { - guard MFMailComposeViewController.canSendMail() else { + 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) ) return } - - let controller = MFMailComposeViewController() - controller.setToRecipients(addresses) - if let subject { - controller.setSubject(subject) - } - - rootViewController?.present(controller, animated: true, completion: nil) + UIApplication.shared.open(url) } } diff --git a/Tests/UITests/TestApp.xctestplan b/Tests/UITests/TestApp.xctestplan index 3f6fca6..be60095 100644 --- a/Tests/UITests/TestApp.xctestplan +++ b/Tests/UITests/TestApp.xctestplan @@ -9,6 +9,15 @@ } ], "defaultOptions" : { + "codeCoverage" : { + "targets" : [ + { + "containerPath" : "container:..\/..", + "identifier" : "SpeziContact", + "name" : "SpeziContact" + } + ] + }, "targetForVariableExpansion" : { "containerPath" : "container:UITests.xcodeproj", "identifier" : "2F6D139128F5F384007C25D6", diff --git a/Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme b/Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme new file mode 100644 index 0000000..6d6bd43 --- /dev/null +++ b/Tests/UITests/UITests.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 032d2d4ffd08e9f010c3f4982b72673560c8f3b2 Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Fri, 23 Jun 2023 00:43:31 -0700 Subject: [PATCH 2/3] Update UI tests --- Tests/UITests/TestAppUITests/SpeziContactsTests.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/UITests/TestAppUITests/SpeziContactsTests.swift b/Tests/UITests/TestAppUITests/SpeziContactsTests.swift index dc7e6e7..5669265 100644 --- a/Tests/UITests/TestAppUITests/SpeziContactsTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziContactsTests.swift @@ -29,6 +29,8 @@ final class ContactsTests: XCTestCase { app.buttons.matching(identifier: "Text").element(boundBy: 0).tap() app.alerts["Text"].scrollViews.otherElements.buttons["Ok"].tap() + app.swipeUp() + XCTAssertEqual(app.buttons.matching(identifier: "Email").count, 2) app.buttons.matching(identifier: "Email").element(boundBy: 0).tap() app.alerts["Email"].scrollViews.otherElements.buttons["Ok"].tap() From a454220def07d811a5dc61a593e783aa1fb8c70e Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Fri, 23 Jun 2023 00:52:23 -0700 Subject: [PATCH 3/3] Fix tests on iOS 17 --- .../UITests/TestAppUITests/SpeziContactsTests.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Tests/UITests/TestAppUITests/SpeziContactsTests.swift b/Tests/UITests/TestAppUITests/SpeziContactsTests.swift index 5669265..a0983fa 100644 --- a/Tests/UITests/TestAppUITests/SpeziContactsTests.swift +++ b/Tests/UITests/TestAppUITests/SpeziContactsTests.swift @@ -27,8 +27,16 @@ final class ContactsTests: XCTestCase { XCTAssertEqual(app.buttons.matching(identifier: "Text").count, 2) app.buttons.matching(identifier: "Text").element(boundBy: 0).tap() - app.alerts["Text"].scrollViews.otherElements.buttons["Ok"].tap() - + if #available(iOS 17.0, *) { + let messages = XCUIApplication(bundleIdentifier: "com.apple.MobileSMS") + XCTAssert(messages.wait(for: .runningForeground, timeout: 2)) + app.activate() + XCTAssert(app.wait(for: .runningForeground, timeout: 2)) + } else { + app.alerts["Text"].scrollViews.otherElements.buttons["Ok"].tap() + } + + sleep(2) app.swipeUp() XCTAssertEqual(app.buttons.matching(identifier: "Email").count, 2)