How to write in info.plist file while building using Swift

Feb/6 By

Recently, I needed to write some specific configurations from one plist to the info.plist file. We have a multi-target project which should use the same values for certain configurations, I searched on multiple resources to try to find the best solution and I found two different ways of doing it, which I would present you here. One is the easy but dirty way and the other is the elegant way of doing it. So, let’s start.

Easy way – User-defined setting

The easiest way of doing this is adding a user-defined setting in your project. Then using it in the Info.plist of the targets that you want to inherit this setting.

You need to select your project and go to Build Settings

 

After that, select the plus icon next to levels, and chose Add User-Defined Setting on the drop menu.

A new setting will appear under the User-Defined section where you can choose the name you are going to use in the plists. There’s no real convention here but I prefer to use uppercase and underscores for the name, let’s define BUNDLE_DISPLAY_NAME as an example.

Then, we just go to the plist where you want to use this defined setting and set it there.

And that’s all you need. You will see your defined setting used by your target.

This solution is also good if you need to use different names, versions or settings depending on your schemes and targets. That’s the power of user-defined settings.

Elegant way – Swift script

There’s another way, the elegant way of doing it. Creating a Swift script to define these values (such as in another plist or some text file), running it as a build phase and writing directly in the info list.

Actually, you can do this using the language of your preference, but I wanted to do it with Swift since I want to practice my use of Swift outside of iOS. I will use Swift 4 to create the script.

First, you need to create the file, I prefer to keep this files outside of the project scope since it’s something that doesn’t affect the app behavior.

If you are lazy and don’t want to read all of this, here you can find the gist file with the final script.

The first thing we need to do is configure our script correctly.

The first line imports macOS SDK if you are working on an iOS or AppleWatch project. If your project is a macOS one you can ignore it. We also need to import Foundation to be able to use FileManager to read/write the list files.

We will use relativePlistFilesFolder to read your Info file, which will usually be in the root directory of your project, in that case just set it to an empty String, but in other cases (like mine) set your real path to your file.

Finally, we will define currentDirectoryPath as a constant just to make our lives easier.

I will start creating our reading plist method.

We will use the string path to read the file and return it as a dictionary. Since we don’t know what we are going to read, we need to set it to Any. We will try to read the file and return the empty dict if it doesn’t exist.

After that we will try to serialize it from a plist to a dict, we will use PropertyListSerialization class to read the file. Since the property list serialization method can throw an error we need to do it inside a do-catch block (unless you want to force the try using the exclamation mark try! ), and return an empty dictionary if it failed or the serialized data if it worked.

After this, we will create our writing method.

This one is really simple, we will cast our dictionary to an  NSDictionary so we can use the write method, and also receive the path where we want to write. Then return true or false depending on the result of the method.

The first thing I do is check if the file exists, if it doesn’t exist then something is wrong with our code and we need to check it.

After that, I just call the write method from NSDictionary with the path of the file and atomically set to false. This method would overwrite the Info.plist file and set our new dictionary with all our changes.

Finally, we can use our code to change our info list.

If you want to write/read Xcode settings, remember to use the raw value. In this case, instead of using Bundle Version we need to use CFBundleVersion if you want to see the raw values available just open your plist file on Xcode and select the option.

You can also set your custom keys here which will be written into the new file.

At the end, we just need to call our write method and return an error if something went wrong.

The last step is to add this as a build phase for every target.

To do this, we need to go to our target and select the Build Phases tab. Under it, we need to click the plus button and select New Run Script Phase.

After that, move the new run script to the first place to make sure you change the list before it’s used and set the path to find your script.

And, that’s all. Build your project and you’ll see the changes we set.

You can find the full code here.

 

I hope you found this tutorial helpful and you can use it in your future projects. If you see any error or an improvement please let me know in the comments.

Thanks and happy swifting!

Adding custom code snippets to Xcode

May/8 By

I am sure you have been there. This is the you can’t remember which time you look in your old code to be sure how to do something you are sure you have done thousands of times but still for some reason you can’t recall it completely so you just copy paste it and then change what you need. If only you could have that in some part in Xcode where with just one click you can use it and continue coding without looking in old projects.

This is where Code Snippets come to action. A great, mostly unknown, tool on Xcode.

In my case, background threading in Swift is one of those snippets I always look for on old projects or somewhere on the internet. That’s why I created a code snippet for it and now I don’t have to do anything else than just start typing “backgroundThreading” and click enter.

You can access the code snippets library in the right bar on Xcode.

Then at the bottom just select the second option.

I will show you the easiest way to add your own snippets here.

First of all you will need to type your code as the way you want to use it in the future. In my case is this:

This is the easiest way to perform a background process and then call the main thread after everything is done.

Once you have your code you need to select it and then just drag it to the code snippets section.

After this a pop up will appear asking you for more information about your new snippet.

  • Title Stands for the main identifier of your snippet
  • Summary A brief description of what it does for future references
  • Platform The default is All, but you can choose between iOS, macOS, tvOS and WatchOS, and according to your project configuration it will be shown or not
  • Language You can choose from a variety of languages, the default is Swift or Objective-C depending on the file you have open
  • Completion Shortcut This is the keyword that you are going to use while coding of autocomplete
  • Completion Scopes Tells Xcode when it should suggest the snippet on your code

After that you just click Done and the new snippet would be available for clicking on the library with the badge User so you know is a custom snippet.

But the easiest way to use it is just start typing the shortcut and then Xcode will suggest it, just click enter and you are done.

And that’s all, you’re ready to go and add as many snippets as you want to make your coding faster and less prompt to errors.

@IBDesignable and @IBInspectable

Nov/22 By

A lot has been written about the @IBInspectable and @IBDesignable properties, but it’s not that easy to find a simple example on how to use them on Swift.

@IBInspectable is a property that you can assign to your custom UIViews variables in order to get a fancy way of assigning values via Interface Bulder. Every variable that has this prefix would appear on the storyboard as far as it uses one of the acceptable run time classes. These are String, Boolean, Numbers, CGSize, CGRect, CGPoint, UIColor UIIMage and NSRange.

Screen Shot 2016-11-22 at 16.39.13

@IBInspectable tells Xcode to compile our view when it’s used on the storyboard, so we can see the changes in real time.

Here we’ve a very simple example on how to do it with a UIView and assign corner radius, border width and color. I’m putting it here because I wasn’t able to find a good simple example on how to do it. Hope it can help you as a base to create your own more complex classes.

 

 

 

Simple Business by Nimbus Themes
Powered by WordPress