![JAR search and dependency download from the Maven repository](/logo.png)
ca.mestevens.ios.utils.XcodeProjectUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xcode-maven-plugin Show documentation
Show all versions of xcode-maven-plugin Show documentation
A maven plugin to facilitate xcode building/dependency management/testing
package ca.mestevens.ios.utils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
import org.apache.maven.plugin.MojoExecutionException;
import ca.mestevens.ios.xcode.parser.exceptions.FileReferenceDoesNotExistException;
import ca.mestevens.ios.xcode.parser.exceptions.InvalidObjectFormatException;
import ca.mestevens.ios.xcode.parser.models.CommentedIdentifier;
import ca.mestevens.ios.xcode.parser.models.PBXBuildFile;
import ca.mestevens.ios.xcode.parser.models.PBXBuildPhase;
import ca.mestevens.ios.xcode.parser.models.PBXFileElement;
import ca.mestevens.ios.xcode.parser.models.PBXTarget;
import ca.mestevens.ios.xcode.parser.models.XCConfigurationList;
import ca.mestevens.ios.xcode.parser.models.XCodeProject;
@Data
public class XcodeProjectUtil {
private String pbxProjLocation;
private XCodeProject xcodeProject;
public XcodeProjectUtil(String pbxProjLocation) throws InvalidObjectFormatException {
this.pbxProjLocation = pbxProjLocation;
this.xcodeProject = new XCodeProject(pbxProjLocation);
}
public void addDependenciesToTarget(String targetName, List dynamicFrameworks, List staticFrameworks, List libraries) throws MojoExecutionException {
try {
List masterFileList = new ArrayList();
if (libraries == null) {
libraries = new ArrayList();
}
if (staticFrameworks == null) {
staticFrameworks = new ArrayList();
}
if (dynamicFrameworks == null) {
dynamicFrameworks = new ArrayList();
}
masterFileList.addAll(libraries);
masterFileList.addAll(staticFrameworks);
masterFileList.addAll(dynamicFrameworks);
//Add the file/build file references
List fileReferenceIdentifiers = addFileReferences(masterFileList);
List libraryBuildIdentifiers = addBuildFiles(libraries, false);
List staticFrameworkBuildIdentifiers = addBuildFiles(staticFrameworks, false);
List dynamicFrameworkBuildIdentifiers = addBuildFiles(dynamicFrameworks, true);
//Get the target
PBXTarget target = getNativeTarget(targetName);
//Link the static libraries
linkLibraries(target.getReference().getIdentifier(), libraryBuildIdentifiers);
linkLibraries(target.getReference().getIdentifier(), staticFrameworkBuildIdentifiers);
//Embed the dynamic libraries
embedLibraries(target, dynamicFrameworkBuildIdentifiers);
//Add the properties to the build configuration
XCConfigurationList configuration = xcodeProject.getConfigurationListWithIdentifier(target.getBuildConfigurationList().getIdentifier());
for(CommentedIdentifier identifier : configuration.getBuildConfigurations()) {
if ((dynamicFrameworks != null && dynamicFrameworks.size() > 0) || (staticFrameworks != null && staticFrameworks.size() > 0)) {
addPropertyToList(identifier.getIdentifier(), "FRAMEWORK_SEARCH_PATHS", "\"${PROJECT_DIR}/target/xcode-dependencies/frameworks/**\"");
addPropertyToString(identifier.getIdentifier(), "LD_RUNPATH_SEARCH_PATHS", "@loader_path/Frameworks");
addPropertyToString(identifier.getIdentifier(), "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks");
}
if (libraries != null && libraries.size() > 0) {
addPropertyToList(identifier.getIdentifier(), "HEADER_SEARCH_PATHS", "\"${PROJECT_DIR}/target/xcode-dependencies/libraries/**\"");
addPropertyToList(identifier.getIdentifier(), "LIBRARY_SEARCH_PATHS", "\"${PROJECT_DIR}/target/xcode-dependencies/libraries/**\"");
}
}
createGroup(fileReferenceIdentifiers);
} catch (Exception ex) {
ex.printStackTrace();
throw new MojoExecutionException(ex.getMessage());
}
}
public void addPropertyToList(String buildConfiguration, String key, String value) {
List propertyList = xcodeProject.getBuildConfigurationPropertyAsList(buildConfiguration, key);
if (propertyList == null) {
propertyList = new ArrayList();
}
if (!propertyList.contains(value)) {
propertyList.add(value);
xcodeProject.setBuildConfigurationProperty(buildConfiguration, key, propertyList);
}
}
public void addPropertyToString(String buildConfiguration, String key, String value) {
String property = xcodeProject.getBuildConfigurationProperty(buildConfiguration, key);
if (property != null) {
if (property.startsWith("\"")) {
property = property.substring(1);
}
if (property.endsWith("\"")) {
property = property.substring(0, property.length() - 1);
}
property = property.trim();
if (!property.contains(value)) {
property = property.concat(" " + value);
}
property = "\"" + property + "\"";
xcodeProject.setBuildConfigurationProperty(buildConfiguration, key, property);
} else {
xcodeProject.setBuildConfigurationProperty(buildConfiguration, key, "\"" + value + "\"");
}
}
public List addBuildFiles(List files, boolean dynamicFrameworks) throws FileReferenceDoesNotExistException {
//Add the framework files as file references and build files
List buildFileReferences = new ArrayList();
for (File dependencyFile : files) {
String fileExtension = dependencyFile.getAbsolutePath().substring(dependencyFile.getAbsolutePath().lastIndexOf('.') + 1);
if (fileExtension.equals("framework") && !dynamicFrameworks) {
File staticLibrary = new File(dependencyFile.getAbsolutePath() + "/" + dependencyFile.getName().substring(0, dependencyFile.getName().lastIndexOf(".")));
if (!staticLibrary.exists()) {
continue;
}
}
String frameworkPath = dependencyFile.getAbsolutePath().substring(dependencyFile.getAbsolutePath().lastIndexOf("target"));
List buildFiles = xcodeProject.getBuildFileWithFileRefPath(frameworkPath);
if (buildFiles.isEmpty()) {
buildFiles = xcodeProject.getBuildFileWithFileRefPath("\"" + frameworkPath + "\"");
}
PBXBuildFile buildFile = null;
for (PBXBuildFile existingFile : buildFiles) {
if (existingFile.getReference().getComment().contains(dependencyFile.getName() + " in Frameworks")) {
buildFile = existingFile;
} else if (existingFile.getReference().getComment().contains(dependencyFile.getName() + " in Embed Frameworks")) {
buildFile = existingFile;
}
}
if (buildFile == null && dynamicFrameworks) {
buildFile = xcodeProject.createBuildFileFromFileReferencePath(frameworkPath, dependencyFile.getName() + " in Embed Frameworks");
buildFile.getSettings().put("ATTRIBUTES", "(CodeSignOnCopy, )");
} else if (buildFile == null) {
buildFile = xcodeProject.createBuildFileFromFileReferencePath(frameworkPath, dependencyFile.getName() + " in Frameworks");
}
buildFileReferences.add(buildFile.getReference());
}
return buildFileReferences;
}
public List addFileReferences(List files) {
List fileReferences = new ArrayList();
for (File dependencyFile : files) {
String frameworkPath = dependencyFile.getAbsolutePath().substring(dependencyFile.getAbsolutePath().lastIndexOf("target"));
PBXFileElement fileReference = xcodeProject.getFileReferenceWithPath(frameworkPath);
if (fileReference == null) {
fileReference = xcodeProject.getFileReferenceWithPath("\"" + frameworkPath + "\"");
if (fileReference == null) {
fileReference = xcodeProject.createFileReference(frameworkPath, "SOURCE_ROOT");
}
}
fileReferences.add(fileReference.getReference());
}
return fileReferences;
}
public void createGroup(List identifiers) {
//Add/Edit the Frameworks group
String frameworkGroupIdentifier = null;
for(PBXFileElement group : xcodeProject.getGroups()) {
if (group.getName() != null && (group.getName().equals("Frameworks") || group.getName().equals("\"Frameworks\""))) {
frameworkGroupIdentifier = group.getReference().getIdentifier();
}
}
if (frameworkGroupIdentifier != null) {
PBXFileElement frameworkGroup = xcodeProject.getGroupWithIdentifier(frameworkGroupIdentifier);
for (CommentedIdentifier fileReference : identifiers) {
boolean found = false;
for (CommentedIdentifier child : frameworkGroup.getChildren()) {
if (child.getComment().equals(fileReference.getComment())) {
found = true;
}
}
if (!found) {
frameworkGroup.addChild(fileReference);
}
}
} else {
String mainGroupIdentifier = xcodeProject.getProject().getMainGroup().getIdentifier();
xcodeProject.createGroup("Frameworks", identifiers, mainGroupIdentifier);
}
}
public void linkLibraries(String targetIdentifier, List identifiers) {
//Get the configuration list identifier for the first target
String existingFrameworksPhaseId = null;
PBXTarget nativeTarget = xcodeProject.getNativeTargetWithIdentifier(targetIdentifier);
for(CommentedIdentifier buildPhaseIdentifier : nativeTarget.getBuildPhases()) {
if (buildPhaseIdentifier.getComment().equals("Frameworks")) {
existingFrameworksPhaseId = buildPhaseIdentifier.getIdentifier();
break;
}
}
//Add the framework build files to the frameworks build phase
PBXBuildPhase frameworksBuildPhase = xcodeProject.getFrameworksBuildPhaseWithIdentifier(existingFrameworksPhaseId);
if (frameworksBuildPhase.getReference().getIdentifier().equals(existingFrameworksPhaseId)) {
for(CommentedIdentifier identifier : identifiers) {
if (!frameworksBuildPhase.getFiles().contains(identifier)) {
frameworksBuildPhase.getFiles().add(identifier);
}
}
}
}
public void embedLibraries(PBXTarget target, List identifiers) {
//If the Embed Frameworks phase doesn't exist, create it
boolean foundExistingPhase = false;
String copyFrameworksBuildPhaseIdentifier = null;
for(CommentedIdentifier buildPhase : target.getBuildPhases()) {
if (buildPhase.getComment().contains("Embed Frameworks")) {
copyFrameworksBuildPhaseIdentifier = buildPhase.getIdentifier();
}
}
for(PBXBuildPhase copyFilesBuildPhase : xcodeProject.getCopyFilesBuildPhases()) {
if (copyFilesBuildPhase.getReference().getIdentifier().equals(copyFrameworksBuildPhaseIdentifier)) {
for(CommentedIdentifier identifier : identifiers) {
boolean foundFile = false;
for (CommentedIdentifier fileIdentifier : copyFilesBuildPhase.getFiles()) {
if (fileIdentifier.getComment().equals(identifier.getComment())) {
foundFile = true;
}
}
if (!foundFile) {
copyFilesBuildPhase.getFiles().add(identifier);
}
}
foundExistingPhase = true;
}
}
if (!foundExistingPhase) {
PBXBuildPhase copyFrameworksBuildPhase = new PBXBuildPhase("PBXCopyFilesBuildPhase", "\"Embed Frameworks\"", identifiers, "\"\"", 10);
xcodeProject.addCopyFilesBuildPhase(target.getReference().getIdentifier(), copyFrameworksBuildPhase);
}
}
public PBXTarget getNativeTarget(String targetName) {
for (PBXTarget target : xcodeProject.getNativeTargets()) {
if (target.getName() != null && (target.getName().equals(targetName) || target.getName().equals("\"" + targetName + "\""))) {
return target;
}
}
return null;
}
public void writeProject() throws IOException {
Files.write(Paths.get(pbxProjLocation), xcodeProject.toString().getBytes());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy