10

Scenario

I want to show the version of my iOS 9 app made with Swift.

What I did

I know how to get the version (let version: String = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String)

I also have a custom label on my home screen.

My problem

My problem is now, that it is not allowed to use your own UIViewController for the splash / launch screen.

Many apps show their version right on that screen. That's why I think that there must be a way how to do it.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Tobonaut
  • 2,245
  • 2
  • 26
  • 39
  • similar to [Adding view controller as launch screen](http://stackoverflow.com/questions/30567177/adding-view-controller-as-launch-screen) – Suragch Aug 10 '16 at 16:19

4 Answers4

55

You can create a script in Build Phases of your project. But make sure you do a couple of things first.

Go to your LaunchScreen.storyboard ViewController and create your version Label. Make sure to name your label to "APP_VERSION" in Identity Inspector pane -> Document -> Label.

Then go to your project's build phases and create your script by clicking the "+" button in the top left corner, then select "New Run Script Phase" from the pulldown menu and then drag it before "Copy Bundle Resources" phase.

UPDATE: My older answer didn't work in the newest Xcode environment. I've fixed the current issues and refactored the script. I'll update when I have the incrementer working. FYI, make sure you reinstall the app for the updated LaunchScreen.storyboard to show (due to system managing caching of the launch screen in latest versions of iOS).

And here's the final working script with shell: /bin/sh in XCode 11 (Swift 5):

#   ON/OFF Script Toggle (script ON with #, script OFF without #)
#exit 0

#   App vesion / Build version constants
sourceFilePath="$PROJECT_DIR/$PROJECT_NAME/Base.lproj/LaunchScreen.storyboard"
versionNumber="$MARKETING_VERSION"
buildNumber="$CURRENT_PROJECT_VERSION"

#   Output version & build numbers into a label on LaunchScreen.storyboard
sed -i .bak -e "/userLabel=\"APP_VERSION\"/s/text=\"[^\"]*\"/text=\"$versionNumber($buildNumber)\"/" "$sourceFilePath"
Repose
  • 2,157
  • 1
  • 24
  • 26
  • I can see the basics of what you're doing here. I've replaced 86400 with a valid path to the SplashScreen.storyboard file however the text of the label doesn't actually change. Anything I can do diagnostically to get this working? – Red Nightingale Jan 10 '17 at 08:53
  • @RedNightingale "86400" is just a name of my project and is a part of the whole path, "$PROJECT_DIR" should get you to the project directory, but there's one more folder, that's why I had to use 86400. Did you move your Run Script above Copy Bundle Resources in Build Phases? Also double check the General tab under "App Icons and Launch Images" -> Launch Screen File, make sure it says LaunchScreen there. Let me know if you get it to work. It took me a few hours to figure out. The text will change every time you Build your project. – Repose Jan 19 '17 at 22:48
  • 4
    This script works and should be the accepted answer. +1 – Philipp Otto Feb 21 '17 at 12:43
  • 2
    Works for me. Adding the Script in Build Phases tripped me up. You have to first click the `+` in the top left corner, then select `New Run Script Phase` from the pull down. – Frak Sep 12 '17 at 04:44
  • @frakman1 Thank you for clarifying one of the steps, I've updated the original answer. Good day. – Repose Sep 13 '17 at 18:34
  • 1
    Side-note: For me, the script crashed when using the combined path of project-dir + plist-file. This was happening because ${INFOPLIST_FILE} already returns the full-path of the plist-file, so only that one is required. – Hans Knöchel Oct 01 '17 at 14:24
  • @hans-knöchel I’ll look into the script again and if your solution works just as well as mine, I’ll update my answer. Thank you! – Repose Nov 01 '17 at 07:31
  • 2
    Works perfectly, when instructions are followed carefully. Two things did trip me up slightly, which was, the position of the Run Script during build, and setting the label identifier to APP_VERSION, so the script knows what to update. To prevent the issue I had: - Put the 'Run Script' BEFORE the 'Copy Bundle Resource' within the 'Build Phases' - For the label identifier make sure it is the Document > Label NOT the Accessibility Identifier within the 'Identity Inspector' which is set to APP_VERSION Alternatively, you could just read the instructions already given properly ;-) – leewilson86 Jan 06 '18 at 11:29
  • 1
    One slight problem is that if you have spaces in your path, the last line doesn’t work. All it takes is quotes around last item. – Owen Godfrey May 25 '18 at 11:00
  • @OwenGodfrey I have same issue, where to put he quotes? What do you mean by last item? For example my path to launch screen is following: /Supporting Files/Base.lproj/LaunchScreen.storyboard – Chanchal Raj Jan 28 '20 at 11:53
  • @ChanchalRaj have you tried escaping your spaces with a backslash or enclosing paths into quotes? – Repose Jan 28 '20 at 14:50
  • 1
    Perfect work! This should be the best answer! And I wonder where you google these property like "$CURRENT_PROJECT_VERSION"? – 李杰駿 Jul 22 '20 at 02:33
  • 1
    @李杰駿 I came across shorter versions for some parts of my older script in other answers on StackOverflow. – Repose Jul 25 '20 at 03:06
  • I personnaly had to change to this to make it works : ```sed -i "" -e "/userLabel=\"APP_VERSION\"/s/text=\"[^\"]*\"/text=\"v$versionNumber ($buildNumber)\"/" "$sourceFilePath"``` – R1' Sep 11 '20 at 11:37
  • 1
    This code also works in Xcode 13 with Swift 5. Thanks @Repose – Mukesh Kumar Dec 16 '22 at 05:42
8

Updated @Repose script

#   ON/OFF Script Toggle (script ON with #, script OFF without #)
#exit 0

#   Increment Build Number Bool (Increment ON with true, increment OFF with false)
shouldIncrement=true

#   App vesion / Build version constants
versionNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_FILE")
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")

#   Increment build number
if [ "$shouldIncrement" = true ]; then
    buildNumber=$(($buildNumber + 1))
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
fi

#   Output version & build numbers into a label on LaunchScreen.storyboard
sed -i bak -e "/userLabel=\"APP_VERSION\"/s/text=\"[^\"]*\"/text=\"Version: $versionNumber Build: $buildNumber\"/" "$PROJECT_DIR/$PROJECT_NAME/Base.lproj/LaunchScreen.storyboard"
5

Its not allowed to use any UIViewController in LaunchScreen thus what other applications does is place a UILabel in LaunchScreen xib/Storyboard and write their version number as text.

There might be some work around's, Its still not preferred or allowed by Apple, don't waste your time searching you will get the following error if you tried to set custom class :

error: Illegal Configuration: Launch screens may not set custom classnames

NOTE: What usually apps do is create another LaunchScreen UIViewConttoller directly after the default launch screen with same design and presented without animation, for example to receive some data.

AaoIi
  • 8,288
  • 6
  • 45
  • 87
  • Yeah, still not allowed as far as I can tell. – Stu P. Feb 14 '17 at 18:25
  • 1
    This answer is not helpful, and does not provide a solution to what the poster asked. This should not be the accepted answer. See the answer provided by 'Repose', that should be the accepted answer. – leewilson86 Jan 06 '18 at 11:31
-2

You can try to do it with LaunchScreen.storyboard. Try to add new LaunchScreen to your project with New File -> User Interface -> Launch Screen It automatically creates a storyboard type of LaunchScreen. Then you can change the initial Launch Screen on project settings -> General in this section:

enter image description here

And work with this storyboard with your custom class

Alexey Pichukov
  • 3,377
  • 2
  • 19
  • 22
  • 2
    Using the LaunchScreen.storyboard still doesn't allow you to use a view controller to set the app version dynamically. – Suragch Aug 10 '16 at 16:17