废话不多说直接上代码
依赖:
<dependency>
<groupId>com.googlecode.plist</groupId>
<artifactId>dd-plist</artifactId>
<version>1.20</version>
</dependency>
工具类util
/**
* ipa解析工具类
* @author wyy
* @return
* @date 2018/9/17
**/
public class IpaUtils{
private String fileName;
private File file;
private MultipartFile multipartFile;
private ZipFile zf;
public IpaUtils(MultipartFile multipartFile) {
this.multipartFile = multipartFile;
}
public IpaUtils(String fileName) {
this.fileName = fileName;
}
public IpaUtils(File file) {
this.file = file;
}
public IpaUtils() {
}
public String getLastIconFileName(NSDictionary dict, String identifier) {
NSDictionary primaryIcon = (NSDictionary) dict.get(identifier);
NSDictionary iconFiles = (NSDictionary) primaryIcon.get("CFBundlePrimaryIcon");
NSObject[] files = ((NSArray) iconFiles.get("CFBundleIconFiles")).getArray();
String name = null;
for (NSObject file : files) {
name = file.toString();
}
return name;
}
public String parse() throws Exception {
ZipInputStream zipIn=null;
if(!ObjectUtils.isEmpty(this.file)){
zipIn = new ZipInputStream(new FileInputStream(this.file));
}else if(!ObjectUtils.isEmpty(this.fileName)){
File f = new File(this.fileName);
zipIn = new ZipInputStream(new FileInputStream(this.fileName));
}
else if(!ObjectUtils.isEmpty(this.multipartFile)){
zipIn = new ZipInputStream(this.multipartFile.getInputStream());
}
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
return null;
}
public String getPlistFromMobileProvisionFile(ByteArrayOutputStream stream) throws UnsupportedEncodingException {
String s = stream.toString("UTF-8");
int i = s.indexOf("<plist version=\"1.0\">");
if (i >= 0) {
s = s.substring(i);
i = s.indexOf("</plist>");
if (i >= 0) {
String plist = s.substring(0, i + "</plist>".length());
return plist;
}
}
return null;
}
public ByteArrayOutputStream readFileToMemory(ZipInputStream zipIn) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytesIn = new byte[4096];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
return bos;
}
}
public IpaInfoBO parse() throws Exception {
IpaInfoBO info = new IpaInfoBO();
ZipInputStream zipIn=null;
if(!ObjectUtils.isEmpty(this.file)){
zipIn = new ZipInputStream(new FileInputStream(this.file));
info.setFileSize(this.file.length());
}else if(!ObjectUtils.isEmpty(this.fileName)){
File f = new File(this.fileName);
info.setFileSize(f.length());
zipIn = new ZipInputStream(new FileInputStream(this.fileName));
}
else if(!ObjectUtils.isEmpty(this.multipartFile)){
info.setFileSize(this.multipartFile.getSize());
zipIn = new ZipInputStream(this.multipartFile.getInputStream());
}
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
if (entry.getName().endsWith(".app/embedded.mobileprovision")) {
ByteArrayOutputStream stream = readFileToMemory(zipIn);
info.setMobileProvisionFile(stream.toByteArray());
String plist = getPlistFromMobileProvisionFile(stream);
if (plist != null) {
NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(plist.getBytes());
info.setProvisioningProfileCreationDate(rootDict.get("CreationDate").toString());
info.setProvisioningProfileExpirationDate(rootDict.get("ExpirationDate").toString());
info.setProvisioningProfileName(rootDict.get("Name").toString());
info.setTeamIdentifier(rootDict.get("TeamIdentifier").toString());
info.setTeamName(rootDict.get("TeamName").toString());
if (rootDict.get("ProvisionedDevices") != null) {
NSObject[] devices = ((NSArray) rootDict.get("ProvisionedDevices")).getArray();
List<String> list = new ArrayList<String>();
for (NSObject device : devices) {
list.add(device.toString());
}
info.setProvisioningProfileDevices(list);
}
} else {
return null;
}
} else if (entry.getName().endsWith(".app/Info.plist")) {
info.setInfoPlistFile(readFileToMemory(zipIn).toByteArray());
NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(info.getInfoPlistFile());
info.setMinimumOSVersion(rootDict.get("MinimumOSVersion").toString());
if(!ObjectUtils.isEmpty(rootDict.get("CFBundleDisplayName"))){
info.setBundleName(rootDict.get("CFBundleDisplayName").toString());
}else {
info.setBundleName(rootDict.get("CFBundleName").toString());
}
if(rootDict.get("BaseURL") != null){
info.setDeployUrl(rootDict.get("BaseURL").toString());
}
info.setBundleVersionString(rootDict.get("CFBundleShortVersionString").toString());
info.setBundleIdentifier(rootDict.get("CFBundleIdentifier").toString());
info.setBuildNumber(rootDict.get("CFBundleVersion").toString());
info.setPlatformVersion(rootDict.get("DTPlatformVersion").toString());
if (rootDict.containsKey("UIRequiredDeviceCapabilities")) {
NSObject[] o = ((NSArray) rootDict.get("UIRequiredDeviceCapabilities")).getArray();
if (o.length > 0) {
info.setRequiredDeviceCapabilities(o[0].toString());
}
}
if (rootDict.containsKey("CFBundleIcons")) {
info.setIPhoneSupport(true);
info.setBundleIconFileName(this.getLastIconFileName(rootDict, "CFBundleIcons"));
} else {
info.setIPhoneSupport(false);
}
if (rootDict.containsKey("CFBundleIcons~ipad")) {
info.setIPadSupport(true);
info.setBundleIconFileName(this.getLastIconFileName(rootDict, "CFBundleIcons~ipad"));
} else {
info.setIPadSupport(false);
}
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
if (info.getBundleIconFileName() != null) {
//zipIn = new ZipInputStream(new FileInputStream(this.fileName));
if(!ObjectUtils.isEmpty(this.file)){
zipIn = new ZipInputStream(new FileInputStream(this.file));
}else if(!ObjectUtils.isEmpty(this.fileName)){
zipIn = new ZipInputStream(new FileInputStream(this.fileName));
}
else if(!ObjectUtils.isEmpty(this.multipartFile)){
zipIn = new ZipInputStream(this.multipartFile.getInputStream());
}
entry = zipIn.getNextEntry();
while (entry != null) {
if (entry.getName().contains("/" + info.getBundleIconFileName())) {
FileOutputStream fos=null;
FileInputStream fis=null;
ByteArrayOutputStream bos=null;
File soureFile=null;
File targetFile=null;
byte[] buffer = null;
try {
//pngconverter再次解析icon
String soureIcon=UUID.randomUUID().toString()+".png";
soureFile=new File(soureIcon);
fos = new FileOutputStream(soureFile);
int chunk = 0;
byte[] data = new byte[1024];
while (-1 != (chunk = zipIn.read(data))) {
fos.write(data, 0, chunk);
}
targetFile=IPngConverter.getIcon(soureFile);
fis = new FileInputStream(targetFile);
bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1)
{
bos.write(b, 0, n);
}
buffer = bos.toByteArray();
info.setBundleIcon(buffer);
//info.setBundleIcon(readFileToMemory(zipIn).toByteArray())
} catch (Exception e) {
e.printStackTrace();
}finally {
fis.close();
bos.close();
fos.close();
new File(soureFile.toURI()).delete();
new File(targetFile.toURI()).delete();
}
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
if (info.getBundleIdentifier() != null) {
return info;
}
return null;
}
/**
* ipa信息实体
* @author wzy
* @return
* @date 2018/9/17
**/
public class IpaInfoBO {
private String minimumOSVersion;
private String bundleVersionString;
private String buildNumber;
private String bundleName;
private String requiredDeviceCapabilities;
private byte[] bundleIcon;
private OutputStream outputStream;
private String platformVersion;
private Boolean iPadSupport;
private Boolean iPhoneSupport;
private String bundleIdentifier;
private String provisioningProfileName;
private String provisioningProfileCreationDate;
private String provisioningProfileExpirationDate;
private List<String>provisioningProfileDevices;
private String teamIdentifier;
private String teamName;
private byte[] infoPlistFile;
private byte[] mobileProvisionFile;
private long fileSize;
private String bundleIconFileName;
/**
* 环境
*/
private String deployUrl;
/**
* 应用平台类型
*/
private String systemPlatform;
public OutputStream getOutputStream() {
return outputStream;
}
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
public String getSystemPlatform() {
return systemPlatform;
}
public void setSystemPlatform(String systemPlatform) {
this.systemPlatform = systemPlatform;
}
public String getMinimumOSVersion() {
return minimumOSVersion;
}
public void setMinimumOSVersion(String minimumOSVersion) {
this.minimumOSVersion = minimumOSVersion;
}
public String getBundleVersionString() {
return bundleVersionString;
}
public void setBundleVersionString(String bundleVersionString) {
this.bundleVersionString = bundleVersionString;
}
public String getBuildNumber() {
return buildNumber;
}
public void setBuildNumber(String buildNumber) {
this.buildNumber = buildNumber;
}
public String getBundleName() {
return bundleName;
}
public void setBundleName(String bundleName) {
this.bundleName = bundleName;
}
public String getRequiredDeviceCapabilities() {
return requiredDeviceCapabilities;
}
public void setRequiredDeviceCapabilities(String requiredDeviceCapabilities) {
this.requiredDeviceCapabilities = requiredDeviceCapabilities;
}
public byte[] getBundleIcon() {
return bundleIcon;
}
public void setBundleIcon(byte[] bundleIcon) {
this.bundleIcon = bundleIcon;
}
public String getPlatformVersion() {
return platformVersion;
}
public void setPlatformVersion(String platformVersion) {
this.platformVersion = platformVersion;
}
public Boolean getIPadSupport() {
return iPadSupport;
}
public void setIPadSupport(Boolean iPadSupport) {
this.iPadSupport = iPadSupport;
}
public Boolean getIPhoneSupport() {
return iPhoneSupport;
}
public void setIPhoneSupport(Boolean iPhoneSupport) {
this.iPhoneSupport = iPhoneSupport;
}
public String getBundleIdentifier() {
return bundleIdentifier;
}
public void setBundleIdentifier(String bundleIdentifier) {
this.bundleIdentifier = bundleIdentifier;
}
public String getProvisioningProfileName() {
return provisioningProfileName;
}
public void setProvisioningProfileName(String provisioningProfileName) {
this.provisioningProfileName = provisioningProfileName;
}
public String getProvisioningProfileCreationDate() {
return provisioningProfileCreationDate;
}
public void setProvisioningProfileCreationDate(String provisioningProfileCreationDate) {
this.provisioningProfileCreationDate = provisioningProfileCreationDate;
}
public String getProvisioningProfileExpirationDate() {
return provisioningProfileExpirationDate;
}
public void setProvisioningProfileExpirationDate(String provisioningProfileExpirationDate) {
this.provisioningProfileExpirationDate = provisioningProfileExpirationDate;
}
public List<String> getProvisioningProfileDevices() {
return provisioningProfileDevices;
}
public void setProvisioningProfileDevices(List<String> provisioningProfileDevices) {
this.provisioningProfileDevices = provisioningProfileDevices;
}
public String getTeamIdentifier() {
return teamIdentifier;
}
public void setTeamIdentifier(String teamIdentifier) {
this.teamIdentifier = teamIdentifier;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public byte[] getInfoPlistFile() {
return infoPlistFile;
}
public void setInfoPlistFile(byte[] infoPlistFile) {
this.infoPlistFile = infoPlistFile;
}
public byte[] getMobileProvisionFile() {
return mobileProvisionFile;
}
public void setMobileProvisionFile(byte[] mobileProvisionFile) {
this.mobileProvisionFile = mobileProvisionFile;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public String getBundleIconFileName() {
return bundleIconFileName;
}
public void setBundleIconFileName(String bundleIconFileName) {
this.bundleIconFileName = bundleIconFileName;
}
public String getDeployUrl() {
return deployUrl;
}
public void setDeployUrl(String deployUrl) {
this.deployUrl = deployUrl;
}
}
演示demo
/**
* 文章——上传
*
* @param file
* @return
*/
@GetMapping("/upload")
public void upLoadArticle(@RequestParam(value = "file") MultipartFile file) throws Exception {
if (Objects.requireNonNull(file.getOriginalFilename()).endsWith(".ipa")) {
String filePath = "D:\\";
File file1 = new File(filePath+file.getOriginalFilename());
ApkUtil apkUtil = new ApkUtil(file1);
String manifestXml = apkUtil.getManifestXml();
IpaUtils reader = new IpaUtils(file1);
IpaInfoBO parse = reader.parse();
}
}