【Java】IOS解析IPA文件中的plist和embedded.mobileprovision

该IPAUtil主要是两个功能。一是解析plist文件,获取版本号、名字、图标等信息。二是解析embedded.mobileprovision文件,获取证书的过期时间。

public class IPAUtil {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(IPAUtil.class);

    /**
     * 读取ipa
     */
    public static IPA readIPA(File ipaFile) throws Exception {
        try (ZipFile zipFile = new ZipFile(ipaFile)) {
            NSDictionary rootDict = null;
            InputStream mobileProvision = null;

            Enumeration e = zipFile.entries();
            while (e.hasMoreElements()) {
                ZipEntry ze = (ZipEntry) e.nextElement();
                if (ze.isDirectory()) {
                    continue;
                }

                String name = ze.getName();
                if (name != null && name.toLowerCase().contains(".app/info.plist")) {
                    rootDict = (NSDictionary) PropertyListParser.parse(zipFile.getInputStream(ze));
                }

                if (name != null && name.toLowerCase().contains(".app/embedded.mobileprovision")) {
                    mobileProvision = zipFile.getInputStream(ze);
                }
            }

            if (rootDict == null) {
                throw new WithOutPlistException("can't find info.plist");
            }

            if (mobileProvision == null) {
                throw new WithOutMobileProvisionException("can't find embedded.mobileprovision");
            }

            IPA ipa = rootDict.toJavaObject(IPA.class)
                    .setIcons(getIcons(rootDict))
                    .setExpirationDate(getExpirationDate(mobileProvision));

            return ipa;
        }
    }

    public static void main(String[] args) throws Exception {

//        IPAUtil ipaUtil = new IPAUtil();
//
//        logger.info(ipaUtil.readIPA(new File("d:\\yl1794\\Desktop\\IOS_plist\\Odin-UC.ipa")).toString());
//
        String time = "2019-07-22T13:38:07Z";
//
        System.out.println(UTCToLong(time));

        System.out.println(DateUtil.parseDate("2019-07-22T13:38:07Z"));

    }


    //----------------------------------private-----------------------------------------
    private static List<String> getIcons(NSDictionary rootDict) {

        NSDictionary iconDict = (NSDictionary) rootDict.get("CFBundleIcons");

        if (iconDict == null) {
            return Collections.emptyList();
        }

        NSDictionary CFBundlePrimaryIcon = (NSDictionary) iconDict.get("CFBundlePrimaryIcon");

        if (CFBundlePrimaryIcon == null) {
            return Collections.emptyList();
        }

        List<String> icons = new ArrayList<>();
        NSArray CFBundleIconFiles = (NSArray) CFBundlePrimaryIcon.get("CFBundleIconFiles");
        for (NSObject nsObject : CFBundleIconFiles.getArray()) {
            icons.add(nsObject.toString().replace(".png", ""));
        }

        return icons;
    }

    private static Long getExpirationDate(InputStream mobileProvision) {
        String key = "<key>ExpirationDate</key>";
        String reg = "^<date>";
        int regLength = reg.length();

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(mobileProvision))) {
            String line = null;
            boolean flag = false;
            while ((line = reader.readLine()) != null) {
                if (!flag) {
                    flag = line.contains(key);
                }
                if (ValidateUtil.match(line.trim(), reg) && flag) {
                    return UTCToLong(line.substring(regLength, line.length() - regLength));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * UTC时间转时间戳
     */
    private static Long UTCToLong(String time) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("UTC"));
        try {
            Date date = df.parse(time);
            logger.info("ExpirationDate: {}", date.toString());
            return date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

}

其中IPA对象为:

@Data
@Accessors(chain = true)
public class IPA {

    private String CFBundleIdentifier;

    private String CFBundleShortVersionString;

    private String CFBundleVersion;

    private String CFBundleDisplayName;

    private List<String> icons;

    private Long ExpirationDate;
}
发布了121 篇原创文章 · 获赞 116 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/Mr_EvanChen/article/details/100565769