fix(ios): make the Shortcuts insert actions findable and write where you told them to - #2218
Merged
Merged
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A user reported that searching "tablepro" in the iOS Shortcuts app shows only Open Connection, while the changelog and the docs promise three actions.
The App Intents code was never broken
Measured two ways against the current tree:
TableProMobile.appbuilt frommainalready ships all three actions inMetadata.appintents/extract.actionsdata(AddRowToTableIntent,AddRowsToTableIntent,OpenConnectionIntent), every oneisDiscoverable, plus all three App Shortcuts inautoShortcuts.swiftc+appintentsmetadataprocessorprobe reproducing the exact shape of the real code (theRowInsertingIntentintermediate protocol,.requiresAuthentication,openAppWhenRun = false,parameterSummary, an optional entity parameter,IntentFile,@IntentParameterDependency, a three-entryAppShortcutsProvider) extracts all three too.So the intermediate protocol is innocent and
RowInsertingIntentis left alone.Two things did go wrong.
The feature has never been in a shipped iOS build.
TableProShortcutsheld exactly one shortcut, Open Connection, until c403e1f on 2026-07-02, which is exactly what the reporter sees.CURRENT_PROJECT_VERSIONhas been 16 since 2026-06-01 and there is no iOS release workflow, so the insert actions have never left the repo. Meanwhile the 0.55.0 changelog entry sits under a macOS version heading and the docs page documented all three actions with no availability information.Even once shipped, an app-name search would not have reached them. Neither insert action carried
categoryNameorsearchKeywords, and neither title contains a brand token.What this changes
categoryName: "Database"andsearchKeywordsto all three intents. Verified in the built app: every action now carries the "TablePro" keyword indescriptionMetadata.Two data bugs found in the same insert path
Both were measured, and both are worse than the reported issue.
String values were escaped with MySQL rules on every engine.
SQLBuilder.escapeStringdoubled backslashes and rewrote newlines regardless of database type, and it backed INSERT, UPDATE and WHERE, so this hit the ordinary iOS app UI too, not just Shortcuts. Measured onsqlite3andduckdb:C:\Users\dat(13 chars) stored asC:\\Users\\dat(14), a real newline stored as the two characters\n, and aWHEREon a storedC:\Users\datmatched 0 rows instead of 1, so editing or deleting such a row silently changed nothing.Per the chosen approach,
escapeStringLiteralis now aDatabaseDriverrequirement with an ANSI default (SQLEscaping.ansiStringLiteral) and a MySQL/MariaDB override (SQLEscaping.backslashStringLiteral), mirroring how the macOS app already does it. The driver is threaded throughbuildInsert,buildUpdateandbuildDeleteand their call sites, includingloadFullValue, which was hand-rolling quote doubling and would have produced an unterminated literal on MySQL for a key ending in a backslash.The Shortcuts insert ignored the schema the user picked.
resolveSchemareturned it and it reachedfetchColumns, but the generated statement used a bare table name. Callingdriver.switchSchema(to:)would not have been enough:MSSQLDriver.switchSchemaonly assigns a local property andexecute(query:)never reads it, so SQL Server would still have written todbo. The statement is schema-qualified instead. Measured on a live PostgreSQL inside a rolled-back transaction: an unqualified insert landed inpublic.events_probewhile the pickeds_reporting.events_probestayed empty, even though the columns had been validated againsts_reporting.Qualification is driven by what the user actually picked, not by
driver.currentSchema.PostgreSQLDriverhardcodescurrentSchematopublicat init and never reads the server'ssearch_path, so qualifying from it would have pinned every unpicked insert topublicand broken connections whose search path points elsewhere. Leaving the picker empty still emits an unqualified statement, exactly as before. The in-app Insert Row screen is likewise left unqualified, so it stays consistent with the SELECT, UPDATE and DELETE on the same screen.Security
Dropping backslash escaping on PostgreSQL is only safe while
standard_conforming_stringsis on. It has defaulted to on since PostgreSQL 9.1, but a session with it off would treat a trailing backslash in a value as an escape and let a crafted value break out of the literal, and a Shortcut that feeds fetched web data into Add Rows to Table is a real path for untrusted input.PostgreSQLDriver.connect()now sets it explicitly.The statement is best-effort on purpose. Redshift runs through the same driver and does not have the parameter at all, so a hard failure would have made every Redshift connection unopenable. The servers that reject it are exactly the ones where the ANSI assumption already holds: Redshift follows the SQL standard for string literals, and PostgreSQL 8.1 and older are far outside what TablePro supports.
Verification
xcodebuildbuild of the TableProMobile scheme: passed.RowInsertPlannerTests,RowInserterTests,RowDetailViewModelTests,DataBrowserViewModelTests,RowPayloadTests: 48 tests,** TEST SUCCEEDED **. Seven are new: schema qualification on PostgreSQL and SQL Server, an unpicked schema staying unqualified, a backslash and a newline surviving on an ANSI dialect, and backslashes still being escaped on MySQL.swiftlint --stricton every changed path: clean.TableProMobile/is outside.swiftlint.yml'sincluded:, so this also cleared a pre-existingset_/where_identifier violation in the function being edited.Metadata.appintents/extract.actionsdatafrom the built app to confirm the keywords landed.No screenshots: the visible change is in Apple's Shortcuts app on a device, which needs a shipped TestFlight build to show.
Not included
Archiving and submitting the TestFlight build. The build number is bumped, but cutting the release is yours.