我可以使用Visual Studio自动增加Info.plist文件中的CFBundleVersion值吗?

时间:2015-08-12 15:35:13

标签: ios visual-studio xamarin

我已经看过使用Xcode甚至Xamarin Studio执行此操作的解决方案,但与Visual Studio没有任何关系。

理想情况下,我希望项目的每个版本都能自动增加Info.plist文件中的CFBundleVersion值。

<key>CFBundleVersion</key>
<string>9</string>

我甚至不知道从哪里开始,并且无法在包含Visual Studio的任何内容上找到文章/博客文章/教程。

这可能吗?

只想添加我在Windows 8.1上使用Visual Studio 2015。

1 个答案:

答案 0 :(得分:0)

与你在同一条船上,就像没有找到合适的解决方案一样,我决定创造自己的。也许迟到总比没有好! :)

在我的情况下,我使用了非常有用的自动版本设置工具(在NuGet上可用)来自动更新我的程序集信息,但希望它也更新Info.plist信息,因为HockeyApp用于跟踪和通知新版本

最后,我将一个最小的C#程序放在一起,该程序读取AssemblyInfo.cs,从那里获取版本信息并编辑Info.plist XML文件并将其写回。

如果我没有进行大量的偏执检查,这将是一个20行程序,以免不可挽回地损坏Info.plist(甚至它会创建该文件的备份)。

“神奇”归结为两种方法,第一种是我在SO上找到的方法:

阅读AssemblyInfo.cs:

private static string GetVersionFromAssemblyInfo(string infile)
{
    var version = String.Empty;

    var readText = File.ReadAllLines(infile);
    var versionInfoLines = readText.Where(t => t.Contains("[assembly: AssemblyVersion"));
    foreach (var item in versionInfoLines)
    {
        version = item.Substring(item.IndexOf('(') + 2, item.LastIndexOf(')') - item.IndexOf('(') - 3);
    }
    return version;
}

编辑Info.plist,其中汇编信息元组的前3个元素变为CFBundleShortVersionString,最后一个元素变为CFBundleVersion HockeyApp用于构建号。

LINQ中的奇怪之处在于Apple在该文件中呈现键/值对的方式有点奇怪:

 private static bool SetVersionInInfoPlist(string infoplistFile, string version, string number)
    {
        var xelements = XDocument.Load(infoplistFile);
        var dict = from el in xelements.Root?.Elements() select el;
        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
        if (dict == null) return false;

        var cfshortversion =
            from el in dict.Descendants("key")
            where el.Value == "CFBundleShortVersionString"
            select el.ElementsAfterSelf().FirstOrDefault();
        ;
        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
        if (cfshortversion == null) return false;
        cfshortversion.FirstOrDefault()?.SetValue(version);

        var cfversion =
            from el in dict.Descendants("key")
            where el.Value == "CFBundleVersion"
            select el.ElementsAfterSelf().FirstOrDefault();

        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
        if (cfversion == null) return false;
        cfversion.FirstOrDefault()?.SetValue(number);

        // Make backup
        try
        {
            File.Copy(infoplistFile, $"{infoplistFile}-backup", true);
        }
        catch (Exception)
        {
            Console.WriteLine($"Failed to create backup of {infoplistFile}. Will not edit.");
            return false;
        }

        try
        {
            using (StringWriter sw = new StringWriter())
            {
                using (XmlWriter xWrite = XmlWriter.Create(sw))
                {
                    xelements.Save(xWrite);
                }
            }
            xelements.Save(infoplistFile);
        }
        catch (Exception)
        {
            Console.WriteLine($"Failed to save the edited {infoplistFile}.");
            return false;
        }

        Console.WriteLine($"Successfully edited and saved new {infoplistFile}.");
        return true;

    }

编辑:我还应该补充一点,我使用Bamboo for CI和构建自动化。因此,该程序成为远程构建代理的功能,然后我可以将其添加为Bamboo构建计划中的任务。