Xplat Automating Version Tool

Overview

Header

Xplat Automating Version Tool

Build status Build Status

Command-line utility to automatically increase iOS / Android / UWP applications version written in Go. It follows Semantic Versioning.

Installation

Windows:

Using Chocolatey:

$ choco install xavtool -version 1.2.1
$ xavtool --version

Using scoop:

$ scoop bucket add gabrielrobert-bucket https://github.com/gabrielrobert/scoop-bucket
$ scoop install xavtool

macOS:

Using brew:

$ brew install gabrielrobert/tap/xavtool
$ xavtool --version

Binaries

Download executables on the release page.

From source:

$ go build
$ go test -v
$ go install
$ xavtool --version

Usage

$ xavtool

NAME:
   xavtool - Command-line utility to automatically increase applications version

USAGE:
   xavtool [global options] command [command options] [arguments...]

VERSION:
   1.2.1

AUTHOR:
   Gabriel Robert <[email protected]>

COMMANDS:
     current, c    List current versions
     increment, i  Increment to next version
     set, s        Set the current project version
     help, h       Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version

increment

$ xavtool increment --help

NAME:
   xavtool increment - Increment to next version

USAGE:
   xavtool increment [command options] [arguments...]

OPTIONS:
   --type value, -t value  major, minor, patch (default: "minor")

set

$ xavtool set --help

NAME:
   xavtool set - Set the current project version

USAGE:
   xavtool set [arguments...]

Typical flow

$ xavtool current
1.0.1 - androidApp (...\test\AndroidManifest.xml)
1.0.1 - iOSApp (...\test\Info.plist)
1.0.1.0 - uwpApp (...\test\Package.appxmanifest)

$ git flow release start '1.1.0'

$ xavtool i
1.0.1: New version: 1.1.0 (...\test\AndroidManifest.xml)
1.0.1: New version: 1.1.0 (...\test\Info.plist)
1.0.1.0: New version: 1.1.0.0 (...\test\Package.appxmanifest)

$ git commit -am "Version bump to 1.1.0"
$ git flow release finish -p

It will update these files:

  • Info.plist
  • AndroidManifest.xml
  • Package.appxmanifest

Results

Info.plist (iOS)

Only these values will be edited:

  1. CFBundleShortVersionString (new version)
  2. CFBundleVersion (new version)

Before:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <!-- ... -->
        <key>CFBundleShortVersionString</key>
        <string>1.0.1</string>
        <key>CFBundleVersion</key>
        <string>1.0.1</string>
        <!-- ... -->
    </dict>
</plist>

After:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <!-- ... -->
        <key>CFBundleShortVersionString</key>
        <string>1.1.0</string>
        <key>CFBundleVersion</key>
        <string>1.1.0</string>
        <!-- ... -->
    </dict>
</plist>

AndroidManifest.xml (Android)

Only these values will be edited:

  1. manifest/@android:versionName (new version)
  2. manifest/@android:versionCode (integer computed this way: (major * 1000000) + (minor * 10000) + (patch * 100))

Before:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.xavtool" 
    android:versionCode="1000100"
    android:versionName="1.0.1">
    <!-- ... -->
</manifest>

After:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android" 
        package="com.example.xavtool" 
        android:versionCode="1010000" 
        android:versionName="1.1.0">
    <!-- ... -->
</manifest>

Package.appxmanifest (UWP)

Only these values will be edited:

  1. Package/Identity/@Version (new version with a revision number set to 0)

Before:

<?xml version="1.0" encoding="utf-8"?>
<Package
    xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
    xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
    xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
    
    <!-- ... -->
    <Identity Name="95748d56-342b-4dae-93f5-aeda0587a1c0" Publisher="CN=gabrielrobert" Version="1.0.1.0"/>
    <!-- ... -->
    
</Package>

After:

<?xml version="1.0" encoding="utf-8"?>
<Package
    xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
    xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
    xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
    
    <!-- ... -->
    <Identity Name="95748d56-342b-4dae-93f5-aeda0587a1c0" Publisher="CN=gabrielrobert" Version="1.1.0.0"/>
    <!-- ... -->
    
</Package>

config.xml (Cordova)

Only these values will be edited:

  1. widget/@version (new version)
  2. widget/@ios-CFBundleVersion (new version)
  3. widget/@android-versionCode (integer computed this way: (major * 1000000) + (minor * 10000) + (patch * 100))

Before:

<?xml version="1.0" encoding="utf-8"?>
<widget 
    id="com.example.xavtool" 
    android-versionCode="1000100" 
    ios-CFBundleVersion="1.0.1" 
    version="1.0.1" 
    xmlns="http://www.w3.org/ns/widgets"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cdv="http://cordova.apache.org/ns/1.0">
  <!-- ... -->
</widget>

After:

<?xml version="1.0" encoding="utf-8"?>
<widget 
    id="com.example.xavtool" 
    android-versionCode="1010000" 
    ios-CFBundleVersion="1.1.0" 
    version="1.1.0" 
    xmlns="http://www.w3.org/ns/widgets"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cdv="http://cordova.apache.org/ns/1.0">
  <!-- ... -->
</widget>

Support

Please open an issue for support.

Contributing

Please contribute using Github Flow. Create a branch, add commits, and open a pull request.

Comments
  • Major.Minor.Patch.Revision format

    Major.Minor.Patch.Revision format

    When running the tool at an Windows app, it throws an exception because the version is recognized by SemVer. Windows uses a fourth number as revision, which does not exists in SemVer.

    Version = A version string in quad notation, "Major.Minor.Build.Revision" [..]

    https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-identity#syntax

    Click to see the exception
    panic: Invalid Semantic Version
    
    goroutine 1 [running]:
    main.check(0x5ea420, 0x14d06220)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/helpers.go:47 +0x36
    main.parse(0x14db1c78, 0x7, 0x14d060d0)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/version.go:30 +0x45
    main.incrementMinor(0x14db1c78, 0x7, 0x4, 0x5c1e39)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/version.go:17 +0x36
    main.increment(0x14d122c0, 0x14d06300, 0x14d122c0)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/actions.go:55 +0x53d
    github.com/urfave/cli.HandleAction(0x5925e0, 0x5cf72c, 0x14d122c0, 0x0, 0x14d2c270)
            /home/travis/gopath/src/github.com/urfave/cli/app.go:501 +0xa2
    github.com/urfave/cli.Command.Run(0x5c2baa, 0x9, 0x0, 0x0, 0x14d063b8, 0x1, 0x1, 0x5c748a, 0x19, 0x0, ...)
            /home/travis/gopath/src/github.com/urfave/cli/command.go:165 +0x3d7
    github.com/urfave/cli.(*App).Run(0x14d02380, 0x14d0e0b0, 0x2, 0x2, 0x0, 0x0)
            /home/travis/gopath/src/github.com/urfave/cli/app.go:259 +0x5cc
    main.main()
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/main.go:19 +0x3a8
    

    The same goes for iOS. The documentation mentions the use of a suffix for development. It gives some examples, but the final format is left to the developer. We use the Major.Minor.Patch.Revision format for that. E.g. 1.0.2.3.

    And for Android, you already reserved room for an extra revision number. E.g. 1000203.

    P.s. I love this tool; it normalizes one of the boring task in Xamarin.

    bug 
    opened by jerone 4
  • Current command

    Current command

    The current command is not consistent in returning the value. Currently it returns...

    • friendly version name for Android.
    • real version for iOS.

    My suggestion is to make this consistent for both platforms. And return both values (version and friendly version name).

    (Windows has only one version type)

    enhancement 
    opened by jerone 3
  • Possible bug in Android versionCode

    Possible bug in Android versionCode

    I think I've identified a possible bug with Android...

    Releasing the app with version 1.99.1 results in android:versionCode="1991". Releasing a new major version of the app with version 2.0.0 will result in a lower android:versionCode="200". Which is not correct.

    Semver doesn't specify a limit of a version number, but releasing more then 99 patches for example will probably never happen in our opinion. But releasing with 11, 12, 13 is a real possibility. That's why we use the optional zero to create the android:versionCode.

    Using the previous example again; releasing the app with version 1.99.1 results in android:versionCode="019901" and then releasing 2.0.0 will result in android:versionCode="020000" (which is higher again).

    And because Android requires an integer, we increase the number with 1000000, resulting in android:versionCode="1019901" and android:versionCode="1020000".

    bug 
    opened by jerone 3
  • What is the result?

    What is the result?

    Very interesting tool!

    I see in the readme that you support:

    • Info.plist
    • AndroidManifest.xml
    • Package.appxmanifest

    But it does not specify what will be used and result into version code and version name/string. As different OS's have different requirements.

    question 
    opened by jerone 2
  • Multiple enhancements

    Multiple enhancements

    • Solve #19 and #18.
    • Add support for Cordova.
    • Project renamed Xamarin Automating Version Tool to Xplat Automating Version Tool
    • It is possible to give a path to all xavtool commands. EX: xavtool c AND xavtool c C:\dev
    opened by gabrielrobert 0
  • panic: interface conversion: interface {} is string, not map[string]interface {}

    panic: interface conversion: interface {} is string, not map[string]interface {}

    If using xavtool 1.2.1-fix on mac or windows following error appears with latest VS 2019 release.

    panic: interface conversion: interface {} is string, not map[string]interface {}

    goroutine 1 [running]:
    github.com/clbanning/mxj.elemListSeq.Less(...)
            /home/travis/gopath/src/github.com/clbanning/mxj/xmlseq.go:812
    github.com/clbanning/mxj.(*elemListSeq).Less(0xc0421b2640, 0x1, 0x0, 0x20)
            <autogenerated>:1 +0x199
    sort.insertionSort(0x66df80, 0xc0421b2640, 0x0, 0x3)
            /home/travis/.gimme/versions/go1.10.7.linux.amd64/src/sort/sort.go:27 +0xa3
    sort.quickSort(0x66df80, 0xc0421b2640, 0x0, 0x3, 0x4)
            /home/travis/.gimme/versions/go1.10.7.linux.amd64/src/sort/sort.go:209 +0x20e
    sort.Sort(0x66df80, 0xc0421b2640)
            /home/travis/.gimme/versions/go1.10.7.linux.amd64/src/sort/sort.go:218 +0x80
    github.com/clbanning/mxj.mapToXmlSeqIndent(0x1, 0xc04206f518, 0xc04216f550, 0xb, 0x608900, 0xc042067bc0, 0xc04206f238, 0x0, 0x0)
            /home/travis/gopath/src/github.com/clbanning/mxj/xmlseq.go:657 +0x1187
    github.com/clbanning/mxj.mapToXmlSeqIndent(0x608901, 0xc04206f518, 0xc04216f348, 0x8, 0x608900, 0xc0420674d0, 0xc04206f528, 0x40b090, 0xc04216f348)
            /home/travis/gopath/src/github.com/clbanning/mxj/xmlseq.go:668 +0x124e
    github.com/clbanning/mxj.Map.XmlSeqIndent(0xc0420674a0, 0x0, 0x0, 0x641b89, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
            /home/travis/gopath/src/github.com/clbanning/mxj/xmlseq.go:518 +0x1f2
    main.androidHandler.applyVersion(0xc0420f0700, 0x481, 0x681, 0xc04216f330, 0x5, 0xc0421a8560, 0x13, 0xc0421a8580, 0xc04206f768, 0x4d6caa)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/android_handler.go:89 +0x43f
    main.androidHandler.changePackageVersion(0xc04200f100, 0x12, 0xc042009180, 0x5, 0xc042009170, 0x7, 0xc042012b90, 0x4d, 0x0, 0xc04216f330, ...)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/android_handler.go:56 +0x82
    main.setVersion(0xc04200f100, 0x12, 0xc042009180, 0x5, 0xc042009170, 0x7, 0xc042012b90, 0x4d, 0x0, 0xc04216f330, ...)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/actions.go:132 +0x122
    main.increment(0xc04207e6e0, 0xc042003000, 0xc04207e6e0)
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/actions.go:72 +0x551
    github.com/urfave/cli.HandleAction(0x5fdb40, 0x6514a0, 0xc04207e6e0, 0x0, 0xc04204c360)
            /home/travis/gopath/src/github.com/urfave/cli/app.go:501 +0xcf
    github.com/urfave/cli.Command.Run(0x64347c, 0x9, 0x0, 0x0, 0xc0420496b0, 0x1, 0x1, 0x647edf, 0x19, 0x0, ...)
            /home/travis/gopath/src/github.com/urfave/cli/command.go:165 +0x484
    github.com/urfave/cli.(*App).Run(0xc0420d0000, 0xc042002400, 0x2, 0x2, 0x0, 0x0)
            /home/travis/gopath/src/github.com/urfave/cli/app.go:259 +0x6ef
    main.main()
            /home/travis/gopath/src/github.com/gabrielrobert/xavtool/main.go:19 +0x480
    

    but calling xavtool -c returns correct versions

    PS C:\XXXXXXXX> .\xavtool.exe c
    1.5.8 [1050800] - YYYYYYY (C:\XXXXXX\Droid\Properties\AndroidManifest.xml)
    1.5.8 [1.5.8] - YYYYYYY (C:\XXXXXX\iOS\Info.plist)
    
    opened by 2mooar 0
  • panic: runtime error: invalid memory address or nil pointer dereference when calling xavtool set

    panic: runtime error: invalid memory address or nil pointer dereference when calling xavtool set

    xavtool Version 1.2.0

    [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x11b9626]

    goroutine 1 [running]:

    main.isIgnored(0x0, 0x0, 0xc42008b0b0) /home/travis/gopath/src/github.com/gabrielrobert/xavtool/finders.go:50 +0x56 main.findManifests.func1(0x7ffeefbfd634, 0x9, 0x0, 0x0, 0x1253ba0, 0xc42008b0b0, 0x30, 0x120ab40) /home/travis/gopath/src/github.com/gabrielrobert/xavtool/finders.go:24 +0x70 path/filepath.Walk(0x7ffeefbfd634, 0x9, 0xc42008b080, 0x0, 0x38) /home/travis/.gimme/versions/go1.10.7.linux.amd64/src/path/filepath/path.go:401 +0x6c main.findManifests(0x7ffeefbfd634, 0x9, 0x134b200, 0x4, 0x4, 0x136b9c0, 0x1, 0x2, 0xc420109948, 0x13b86c8) /home/travis/gopath/src/github.com/gabrielrobert/xavtool/finders.go:22 +0x10d main.set(0xc4200bc6e0, 0xc420083700, 0xc4200bc6e0) /home/travis/gopath/src/github.com/gabrielrobert/xavtool/actions.go:98 +0x176 github.com/urfave/cli.HandleAction(0x11e7140, 0x1237d48, 0xc4200bc6e0, 0x0, 0xc4200b82a0) /home/travis/gopath/src/github.com/urfave/cli/app.go:501 +0xc8 github.com/urfave/cli.Command.Run(0x122a2ca, 0x3, 0x0, 0x0, 0xc4200836b0, 0x1, 0x1, 0x1230e5f, 0x1f, 0x0, ...) /home/travis/gopath/src/github.com/urfave/cli/command.go:165 +0x47d github.com/urfave/cli.(*App).Run(0xc420122000, 0xc42008a090, 0x3, 0x3, 0x0, 0x0) /home/travis/gopath/src/github.com/urfave/cli/app.go:259 +0x6e8 main.main() /home/travis/gopath/src/github.com/gabrielrobert/xavtool/main.go:19 +0x479

    Running on a macOS Hosted VSTS build agent and installed via Homebrew. Had been using version 1.1.2 for months without any issues.

    opened by kylerdanielster 7
  • Enhancement: Environment Based Semver

    Enhancement: Environment Based Semver

    It would be nice for us enterprise devs that test in different environments to put an environment string on the end of the Semver and have it preserved during increment operations.

    We follow the conventions of NormalSemVer_EnvironmentName (QSB/RC/STAGING). Prod is just SemVer, no string.

    opened by adamhill 1
  • .csproj file support

    .csproj file support

    As state here, new .csproj file supports versioning.

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net461</TargetFramework>
        <Version>1.2.3.4</Version>
        <Authors>Author 1</Authors>
        <Company>Company XYZ</Company>
        <Product>Product 2</Product>
        <PackageId>MyApp</PackageId>
        <AssemblyVersion>2.0.0.0</AssemblyVersion>
        <FileVersion>3.0.0.0</FileVersion>
        <NeutralLanguage>en</NeutralLanguage>
        <Description>Description here</Description>
        <Copyright>Copyright</Copyright>
        <PackageLicenseUrl>License URL</PackageLicenseUrl>
        <PackageProjectUrl>Project URL</PackageProjectUrl>
        <PackageIconUrl>Icon URL</PackageIconUrl>
        <RepositoryUrl>Repo URL</RepositoryUrl>
        <RepositoryType>Repo type</RepositoryType>
        <PackageTags>Tags</PackageTags>
        <PackageReleaseNotes>Release</PackageReleaseNotes>
      </PropertyGroup>
    

    It could be interesting to support them.

    enhancement new-handler 
    opened by gabrielrobert 0
  • AssemblyInfo support

    AssemblyInfo support

    As state here:

    AssemblyInfo.cs contains information about your assembly, like name, description, version, etc. You can find more details about its content reading the comments that are included in it. If you delete it, your assembly will be compiled with no information, i.e., in the Details tab of the file properties, you will see no name, no description, version 0.0.0.0, etc.

    It could be interesting to support AssemblyInfo.cs files.

    enhancement new-handler 
    opened by gabrielrobert 2
Releases(1.2.1-fix)
Owner
Gabriel Robert
Breaking the build @ Fourwaves
Gabriel Robert
An adorable little framework and command line tool for interacting with SourceKit.

SourceKitten An adorable little framework and command line tool for interacting with SourceKit. SourceKitten links and communicates with sourcekitd.fr

JP Simard 2.1k Jan 5, 2023
Xcode-compatible build tool.

xcbuild xcbuild is an Xcode-compatible build tool with the goal of providing faster builds, better documentation of the build process and running on m

Meta Archive 2k Dec 11, 2022
Network debugging made easy,This network debugging tool is developed based on the swift version of Wormholy.

Start debugging iOS network calls like a wizard, without extra code! Wormholy makes debugging quick and reliable. What you can do: No code to write an

null 21 Dec 14, 2022
A minimalistic, thread safe, non-boilerplate and super easy to use version of Active Record on Core Data.

Skopelos A minimalistic, thread-safe, non-boilerplate and super easy to use version of Active Record on Core Data. Simply all you need for doing Core

Alberto De Bortoli 235 Sep 9, 2022
An easy way to create and layout UI components for iOS (Swift version).

Introduction Cupcake is a framework that allow you to easily create and layout UI components for iOS 8.0+. It use chaining syntax and provides some fr

nerdycat 288 Oct 9, 2022
UI Component. This is a copy swipe-panel from app: Apple Maps, Stocks. Swift version

ContainerController UI Component. This is a copy swipe-panel from app: https://www.apple.com/ios/maps/ Preview Requirements Installation CocoaPods Swi

Rustam 419 Dec 12, 2022
Monitor iOS app version easily.

AppVersionMonitor Monitor iOS app version easily. You can get previous version and installation history. Usage To run the example project, clone the r

エウレカ 256 Jan 4, 2023
Notify users when a new version of your app is available and prompt them to upgrade.

Siren ?? Notify users when a new version of your app is available and prompt them to upgrade. Table of Contents Meta About Features Screenshots Ports

Arthur Ariel Sabintsev 4.1k Dec 27, 2022
iOS version of emitron

emitron (iOS) emitron is the code name for the raywenderlich.com app. This repo contains the code for the iOS version of the app. Contributing To cont

razeware 331 Dec 2, 2022
An unofficial version of the Sandwiches app and pre-built materials similar to those used in the Introduction to SwiftUI session video from WWDC20

Unofficial Sandwiches The WWDC20 Session Introduction to SwiftUI provides a tutorial-like walk-through of building a list-detail SwiftUI app from scra

James Dempsey 94 Feb 11, 2022
Recreating a fully functional version of iOS 4 in SwiftUI.

Updates: Version 1.0 is currently available ?? While I work on fixing an issue in Xcode 12.5+ with LazyVGrid, I recommend you build using Xcode 12.4 a

null 2.9k Jan 1, 2023
A package to help track how often the user opened the app and if they opened it in the current version before.

AppOpenTracker AppOpenTracker provides an observable AppOpenTracker.shared instance that can be used to track the last version that the app was opened

Florian Schweizer 9 Oct 29, 2022
The iOS version of 2048, made using SpriteKit

2048 This is a derivative and the iOS version of the game 2048. In the very unlikely case that you don't know what it is, you can check it out here. M

Danqing Liu 1.1k Dec 31, 2022
Doom Classic for iOS version 2

DOOM Classic iOS v3.0 GPL source release =============================================== This file contains the following sections: GENERAL NOTES LI

id Software 298 Dec 22, 2022
iPhone and iPod Touch version of Skeleton Key: is an addictive and unique puzzle game in which you shift keys around the board unlocking treasure chests. Made with cocos2d-iphone.

Skeleton Key (iOS) Skeleton Key is an addictive and unique puzzle game in which you shift keys around the board unlocking treasure chests. It's availa

null 117 Jun 6, 2022
Native (Swift) version of Open Food Facts for iOS. Coders & Decoders welcome 🤳🥫 😊

Open Food Facts iPhone and iPad app What is Open Food Facts? What can I work on ? Open Food Facts is a food products database made by everyone, for ev

Open Food Facts 299 Jan 4, 2023
📱📲 Navigate between view controllers with ease. 💫 🔜 More stable version (written in Swift 5) coming soon.

CoreNavigation ?? ?? Navigate between view controllers with ease. ?? ?? More stable version (written in Swift 5) coming soon. Getting Started API Refe

Aron Balog 69 Sep 21, 2022
React Native version of the Podverse Mobile App

Podverse Podverse is an open source podcast manager for iOS, Android, and web. Check us out at podverse.fm! Free features: Subscribe to podcasts Auto-

Podverse 80 Dec 30, 2022
Recreating a fully functional version of iOS 4 in SwiftUI.

Updates: Version 1.0 is currently available ?? While I work on fixing an issue in Xcode 12.5+ with LazyVGrid, I recommend you build using Xcode 12.4 a

null 2.9k Jan 4, 2023
Checks if there is a newer version of your app in the AppStore and alerts the user to update.

YiAppUpdater Checks if there is a newer version of your app in the AppStore and alerts the user to update. Installation YiAppUpdater is available thro

coderyi 4 Mar 17, 2022