diff --git a/aqt/updater.py b/aqt/updater.py
index 23920223..86f78b9c 100644
--- a/aqt/updater.py
+++ b/aqt/updater.py
@@ -24,6 +24,7 @@
 import re
 import subprocess
 from logging import getLogger
+from typing import Union
 
 import patch
 
@@ -33,6 +34,26 @@
 from aqt.metadata import SimpleSpec, Version
 
 
+def default_desktop_arch_dir(host: str, version: Union[Version, str]) -> str:
+    version: Version = version if isinstance(version, Version) else Version(version)
+    if host == "linux":
+        return "gcc_64"
+    elif host == "mac":
+        return "macos" if version in SimpleSpec(">=6.1.2") else "clang_64"
+    else:  # Windows
+        # This is a temporary solution. This arch directory cannot exist for many versions of Qt.
+        # TODO: determine this dynamically
+        return "mingw81_64"
+
+
+def dir_for_version(ver: Version) -> str:
+    return "5.9" if ver == Version("5.9.0") else f"{ver.major}.{ver.minor}.{ver.patch}"
+
+
+def unpatched_path(os_name: str, final_component: str) -> str:
+    return ("/home/qt/work/install" if os_name == "linux" else "/Users/qt/work/install") + "/" + final_component
+
+
 class Updater:
     def __init__(self, prefix: pathlib.Path, logger):
         self.logger = logger
@@ -160,30 +181,14 @@ def patch_qmake(self):
                 newpath=bytes(str(self.prefix), "UTF-8"),
             )
 
-    def patch_qmake_script(self, base_dir, qt_version, os_name):
-        if os_name == "linux":
-            self.logger.info("Patching {}/bin/qmake".format(self.prefix))
-            self._patch_textfile(
-                self.prefix / "bin" / "qmake",
-                "/home/qt/work/install/bin",
-                "{}/{}/{}/bin".format(base_dir, qt_version, "gcc_64"),
-            )
-        elif os_name == "mac":
-            self.logger.info("Patching {}/bin/qmake".format(self.prefix))
-            self._patch_textfile(
-                self.prefix / "bin" / "qmake",
-                "/Users/qt/work/install/bin",
-                "{}/{}/{}/bin".format(base_dir, qt_version, "clang_64"),
-            )
-        elif os_name == "windows":
-            self.logger.info("Patching {}/bin/qmake.bat".format(self.prefix))
-            self._patch_textfile(
-                self.prefix / "bin" / "qmake.bat",
-                "/Users/qt/work/install/bin",
-                "{}\\{}\\{}\\bin".format(base_dir, qt_version, "mingw81_64"),
-            )
-        else:
-            pass
+    def patch_qmake_script(self, base_dir, qt_version: str, os_name):
+        arch_dir = default_desktop_arch_dir(os_name, qt_version)
+        sep = "\\" if os_name == "windows" else "/"
+        patched = sep.join([base_dir, qt_version, arch_dir, "bin"])
+        unpatched = unpatched_path(os_name, "bin")
+        qmake_path = self.prefix / "bin" / ("qmake.bat" if os_name == "windows" else "qmake")
+        self.logger.info(f"Patching {qmake_path}")
+        self._patch_textfile(qmake_path, unpatched, patched)
 
     def patch_qtcore(self, target):
         """patch to QtCore"""
@@ -235,15 +240,8 @@ def set_license(self, base_dir, qt_version, arch_dir):
 
     def patch_target_qt_conf(self, base_dir, qt_version, arch_dir, os_name):
         target_qt_conf = self.prefix / "bin" / "target_qt.conf"
-        if os_name == "linux":
-            old_targetprefix = "Prefix=/home/qt/work/install/target"
-            new_hostprefix = "HostPrefix=../../gcc_64"
-        elif os_name == "mac":
-            old_targetprefix = "Prefix=/Users/qt/work/install/target"
-            new_hostprefix = "HostPrefix=../../clang_64"
-        else:
-            old_targetprefix = "Prefix=/Users/qt/work/install/target"
-            new_hostprefix = "HostPrefix=../../mingw81_64"
+        old_targetprefix = f'Prefix={unpatched_path(os_name, "target")}'
+        new_hostprefix = f"HostPrefix=../../{default_desktop_arch_dir(os_name, qt_version)}"
         new_targetprefix = "Prefix={}".format(str(pathlib.Path(base_dir).joinpath(qt_version, arch_dir, "target")))
         new_hostdata = "HostData=../{}".format(arch_dir)
         self._patch_textfile(target_qt_conf, old_targetprefix, new_targetprefix)
@@ -260,7 +258,7 @@ def update(cls, target: TargetConfig, base_dir: str):
         arch = target.arch
         version = Version(target.version)
         os_name = target.os_name
-        version_dir = "5.9" if version == Version("5.9.0") else target.version
+        version_dir = dir_for_version(version)
         if arch is None:
             arch_dir = ""
         elif arch.startswith("win64_mingw"):
@@ -274,8 +272,8 @@ def update(cls, target: TargetConfig, base_dir: str):
                 arch_dir = b + "_" + a
             else:
                 arch_dir = arch[6:]
-        elif version in SimpleSpec(">=6.1.2") and os_name == "mac" and arch == "clang_64":
-            arch_dir = "macos"
+        elif os_name == "mac" and arch == "clang_64":
+            arch_dir = default_desktop_arch_dir(os_name, version)
         else:
             arch_dir = arch
         try:
diff --git a/ci/generate_azure_pipelines_matrices.py b/ci/generate_azure_pipelines_matrices.py
index ce7879b4..b6bd5456 100644
--- a/ci/generate_azure_pipelines_matrices.py
+++ b/ci/generate_azure_pipelines_matrices.py
@@ -269,6 +269,7 @@ def __init__(self, platform, build_jobs):
 mac_build_jobs.extend(
     [
         BuildJob("install-qt", "5.15.2", "mac", "ios", "ios", "ios"),
+        BuildJob("install-qt", "6.2.2", "mac", "ios", "ios", "ios", module="qtsensors"),
         BuildJob(
             "install-qt", "6.1.0", "mac", "android", "android_armv7", "android_armv7"
         ),
diff --git a/ci/steps.yml b/ci/steps.yml
index 8eb16d01..aaa0d58a 100644
--- a/ci/steps.yml
+++ b/ci/steps.yml
@@ -54,7 +54,8 @@ steps:
           if [[ "$(HOST)" == "windows" ]]; then
             python -m aqt install-qt $(HOST) desktop $(QT_VERSION) mingw81_64 --archives qtbase
           else
-            python -m aqt install-qt $(HOST) desktop $(QT_VERSION) --archives qtbase
+            # qtdeclarative contains `qmlimportscanner`: necessary for ios builds, Qt6+
+            python -m aqt install-qt $(HOST) desktop $(QT_VERSION) --archives qtbase qtdeclarative
           fi
         fi
         if [[ "$(OUTPUT_DIR)" != "" ]]; then
@@ -174,6 +175,21 @@ steps:
     condition: and(eq(variables['TARGET'], 'android'), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')), ne(variables['SUBCOMMAND'], 'list'), ne(variables['SUBCOMMAND'], 'install-tool'))
     displayName: Build accelbubble example application to test for android
 
+  ##----------------------------------------------------
+  # for iOS target
+  - bash: |
+      set -ex
+      mkdir $(Build.BinariesDirectory)/tests
+      (cd $(Build.BinariesDirectory)/tests; 7zr x $(Build.SourcesDirectory)/ci/accelbubble.7z)
+      export PATH=$(QT_BINDIR):$PATH
+      qmake $(Build.BinariesDirectory)/tests/accelbubble
+      make
+    condition: |
+        and(eq(variables['TARGET'], 'ios'), 
+            ne(variables['SUBCOMMAND'], 'list'), 
+            ne(variables['SUBCOMMAND'], 'install-tool'))
+    displayName: Build accelbubble example application to test for ios
+
   ##----------------------------------------------------
   # Cache Powershell Modules in $MODULES_FOLDER
   - task: Cache@2
diff --git a/tests/test_install.py b/tests/test_install.py
index a1abb93b..64478f20 100644
--- a/tests/test_install.py
+++ b/tests/test_install.py
@@ -574,7 +574,117 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
                 r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
                 r"Downloading qtbase...\n"
                 r"Finished installation of qtbase-windows-android_armv7.7z in .*\n"
-                r"Patching .*/bin/qmake.bat\n"
+                r"Patching .*6\.1\.0[/\\]android_armv7[/\\]bin[/\\]qmake.bat\n"
+                r"Finished installation\n"
+                r"Time elapsed: .* second"
+            ),
+        ),
+        (
+            "install-qt linux android 6.3.0 android_arm64_v8a".split(),
+            "linux",
+            "android",
+            "6.3.0",
+            "android_arm64_v8a",
+            "android_arm64_v8a",
+            "linux_x64/android/qt6_630_arm64_v8a/Updates.xml",
+            [
+                MockArchive(
+                    filename_7z="qtbase-linux-android_arm64_v8a.7z",
+                    update_xml_name="qt.qt6.630.android_arm64_v8a",
+                    contents=(
+                        # Qt 6 non-desktop should patch qconfig.pri, qmake script and target_qt.conf
+                        PatchedFile(
+                            filename="mkspecs/qconfig.pri",
+                            unpatched_content="... blah blah blah ...\n"
+                            "QT_EDITION = Not OpenSource\n"
+                            "QT_LICHECK = Not Empty\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "QT_EDITION = OpenSource\n"
+                            "QT_LICHECK =\n"
+                            "... blah blah blah ...\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/target_qt.conf",
+                            unpatched_content="Prefix=/home/qt/work/install/target\n"
+                            "HostPrefix=../../\n"
+                            "HostData=target\n",
+                            patched_content="Prefix={base_dir}{sep}6.3.0{sep}android_arm64_v8a{sep}target\n"
+                            "HostPrefix=../../gcc_64\n"
+                            "HostData=../android_arm64_v8a\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/qmake",
+                            unpatched_content="... blah blah blah ...\n"
+                            "/home/qt/work/install/bin\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "{base_dir}/6.3.0/gcc_64/bin\n"
+                            "... blah blah blah ...\n",
+                        ),
+                    ),
+                ),
+            ],
+            re.compile(
+                r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
+                r"Downloading qtbase...\n"
+                r"Finished installation of qtbase-linux-android_arm64_v8a.7z in .*\n"
+                r"Patching .*6\.3\.0[/\\]android_arm64_v8a[/\\]bin[/\\]qmake\n"
+                r"Finished installation\n"
+                r"Time elapsed: .* second"
+            ),
+        ),
+        (
+            "install-qt mac ios 6.1.2".split(),
+            "mac",
+            "ios",
+            "6.1.2",
+            "ios",
+            "ios",
+            "mac_x64/ios/qt6_612/Updates.xml",
+            [
+                MockArchive(
+                    filename_7z="qtbase-mac-ios.7z",
+                    update_xml_name="qt.qt6.612.ios",
+                    contents=(
+                        # Qt 6 non-desktop should patch qconfig.pri, qmake script and target_qt.conf
+                        PatchedFile(
+                            filename="mkspecs/qconfig.pri",
+                            unpatched_content="... blah blah blah ...\n"
+                            "QT_EDITION = Not OpenSource\n"
+                            "QT_LICHECK = Not Empty\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "QT_EDITION = OpenSource\n"
+                            "QT_LICHECK =\n"
+                            "... blah blah blah ...\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/target_qt.conf",
+                            unpatched_content="Prefix=/Users/qt/work/install/target\n"
+                            "HostPrefix=../../\n"
+                            "HostData=target\n",
+                            patched_content="Prefix={base_dir}{sep}6.1.2{sep}ios{sep}target\n"
+                            "HostPrefix=../../macos\n"
+                            "HostData=../ios\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/qmake",
+                            unpatched_content="... blah blah blah ...\n"
+                            "/Users/qt/work/install/bin\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "{base_dir}/6.1.2/macos/bin\n"
+                            "... blah blah blah ...\n",
+                        ),
+                    ),
+                ),
+            ],
+            re.compile(
+                r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
+                r"Downloading qtbase...\n"
+                r"Finished installation of qtbase-mac-ios.7z in .*\n"
+                r"Patching .*6\.1\.2[/\\]ios[/\\]bin[/\\]qmake\n"
                 r"Finished installation\n"
                 r"Time elapsed: .* second"
             ),