diff --git a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java index d60f5bea..2f3b7bc1 100644 --- a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java +++ b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java @@ -144,7 +144,7 @@ private MobileProvision getProvisioningProfile() throws IOException { if (providedMobileProvision == null || providedMobileProvision.equals(mobileProvision.getName())) { this.identity = identity; - Logger.logDebug("Got provisioning profile: " + mobileProvision.getName()); + Logger.logDebug("Got provisioning profile: " + mobileProvision.getName() + " from " + mobileProvision.getProvisioningPath()); return mobileProvision; } } @@ -206,7 +206,7 @@ private MobileProvision tryModifiedBundleId(Identity identity, String bundleId, private List retrieveValidMobileProvisions() { final LocalDate now = LocalDate.now(); if (mobileProvisions == null) { - mobileProvisions = retrieveAllMobileProvisions(); + mobileProvisions = getProvisioningProfiles(); } return mobileProvisions.stream() .filter(provision -> { @@ -216,8 +216,17 @@ private List retrieveValidMobileProvisions() { .collect(Collectors.toList()); } - public static List retrieveAllMobileProvisions() { - Path provisionPath = Paths.get(System.getProperty("user.home"), "Library", "MobileDevice", "Provisioning Profiles"); + public static List getProvisioningProfiles() { + // Starting Xcode 16+: + Path provisionPath = Paths.get(System.getProperty("user.home"), "Library", "Developer", "Xcode", "UserData", "Provisioning Profiles"); + List provisions = new ArrayList<>(retrieveAllMobileProvisionsFromPath(provisionPath)); + // Before Xcode 16: + provisionPath = Paths.get(System.getProperty("user.home"), "Library", "MobileDevice", "Provisioning Profiles"); + provisions.addAll(retrieveAllMobileProvisionsFromPath(provisionPath)); + return provisions; + } + + private static List retrieveAllMobileProvisionsFromPath(Path provisionPath) { if (!Files.exists(provisionPath) || !Files.isDirectory(provisionPath)) { Logger.logSevere("Invalid provisioning profiles folder at " + provisionPath.toString()); return Collections.emptyList(); diff --git a/src/main/java/com/gluonhq/substrate/util/macos/CodeSigning.java b/src/main/java/com/gluonhq/substrate/util/macos/CodeSigning.java index df7edddc..e317c111 100644 --- a/src/main/java/com/gluonhq/substrate/util/macos/CodeSigning.java +++ b/src/main/java/com/gluonhq/substrate/util/macos/CodeSigning.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Gluon + * Copyright (c) 2019, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -377,7 +377,8 @@ private ProvisionProfile getProvisioningProfile() { .findFirst() .orElse(null); } - Logger.logDebug("Provisioning profile: " + (provisionProfile != null ? provisionProfile.getName() : null)); + Logger.logDebug("Got provisioning profile: " + (provisionProfile != null ? + provisionProfile.getName() + " from " + provisionProfile.getProvisioningPath() : null)); return provisionProfile; } @@ -393,18 +394,27 @@ private ProvisionProfile findProvisionProfile(Identity identity, String bundleId private List retrieveValidProvisionProfiles() { final LocalDate now = LocalDate.now(); if (provisionProfiles == null) { - provisionProfiles = retrieveAllProvisionProfiles().stream() + provisionProfiles = getProvisioningProfiles(); + } + return provisionProfiles.stream() .filter(provision -> { LocalDate expirationDate = provision.getExpirationDate(); return expirationDate != null && !expirationDate.isBefore(now); }) .collect(Collectors.toList()); - } - return provisionProfiles; } - private static List retrieveAllProvisionProfiles() { - Path provisionPath = Paths.get(System.getProperty("user.home"), "Library", "MobileDevice", "Provisioning Profiles"); + private static List getProvisioningProfiles() { + // Starting Xcode 16+: + Path provisionPath = Paths.get(System.getProperty("user.home"), "Library", "Developer", "Xcode", "UserData", "Provisioning Profiles"); + List provisions = new ArrayList<>(retrieveAllProvisionProfilesFromPath(provisionPath)); + // Before Xcode 16: + provisionPath = Paths.get(System.getProperty("user.home"), "Library", "MobileDevice", "Provisioning Profiles"); + provisions.addAll(retrieveAllProvisionProfilesFromPath(provisionPath)); + return provisions; + } + + private static List retrieveAllProvisionProfilesFromPath(Path provisionPath) { if (!Files.exists(provisionPath) || !Files.isDirectory(provisionPath)) { Logger.logSevere("Invalid provisioning profiles folder at " + provisionPath.toString()); return Collections.emptyList(); diff --git a/src/test/java/com/gluonhq/substrate/IOSTest.java b/src/test/java/com/gluonhq/substrate/IOSTest.java index a983b392..10cb4750 100644 --- a/src/test/java/com/gluonhq/substrate/IOSTest.java +++ b/src/test/java/com/gluonhq/substrate/IOSTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Gluon + * Copyright (c) 2019, 2024, Gluon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -97,7 +97,7 @@ void testSigning() { @Test void testProvisioning() { assumeTrue(!isCI()); - List provisions = CodeSigning.retrieveAllMobileProvisions(); + List provisions = CodeSigning.getProvisioningProfiles(); assertNotNull(provisions); assertFalse(provisions.isEmpty()); }