Changing UIApplication base class

When developing an iOS application you might get into a situation when you need to change the UIApplication base class. It is often a requirement when using various MDM SDKs, like the Mobile Iron AppConnect SDK. There are two ways to do that in a Swift application, both with some advantages and disadvantages.

Declarative method with Info.plist

The first method to change the UIApplication base class is using Info.plist. It is quite simple, you just need to add a new key NSPrincipalClass with a string value representing the name of the desired class, like AppConnectUIApplication when using the Mobile Iron AppConnect SDK.

<key>NSPrincipalClass</key>
<string>AppConnectUIApplication</string>

No actual code changes are required.

Code method with main.swift

The second method is a bit more complicated but more flexible at the same time. First you need to remove @UIApplicationMain from your AppDelegate class definition. Then you add a main.swift to the root of your project that looks like this

import AppConnect
import UIKit

UIApplicationMain(
    CommandLine.argc,
    CommandLine.unsafeArgv, 
    ACUIApplicationClassName,
    NSStringFromClass(AppDelegate.self)
)

The third parameter in the UIApplicationMain call is the name of the desired class, ACUIApplicationClassName in this example.

[Read More]
iOS  Swift  Xcode 

Creating iOS context menu with highlight and dim

The iOS messaging application I work on features a context menu in the chat. You long-press any message in the chat and the context menu appears. This menu was originally implemented using the standard UIMenuController.

The UIMenuController is an old-style iOS API that is hard to use and does not work very well. In some situations tapping its items just did not call the assigned selectors and the menu did not work.

As part of the ongoing redesign of the application I decided to implement a new custom context menu that would look as the designer imagined and more importantly work reliably. I did not want to use any 3rd party library to keep it as simple and possible.

Using just UIKit I came up with a context menu with a dim effect and a highlight on the selected item

Here is how I approached building it.

[Read More]
iOS  Swift  Xcode 

Changing UIAlertAction text color

If you use the standard iOS UIAlertController to present the user with a list of actions, there is not much you can do about styling each of the UIAlertActions shown.

The text of the shown UIAlertAction uses the UIView’s tint color, so you can use the UIAppearence API to change it to any color you want, but the same color for all the UIAlertActions. If you set the style to destructive instead of default, the text is shown as red, not affected by the tint color.

UIAlertController with one default and one destructive action might then look like this with dark blue set as the global tint color using UIAppearence:

The red color for the destructive option does not look that great, especially if your app uses a different shade of red everywhere else.

If you dive deep into Apple documentation you will find a KVC called titleTextColor. This KVC allows you to set exactly what you need, the color for the UIAlertAction text.

[Read More]
iOS  Xcode 

Editing macOS app About dialog

When you create a macOS app and keep the default menu, you automatically get an About dialog. This dialog shows basic info about the app.

If you want to add more information to this dialog there is no obvious way to do it. You need to start reading the Apple documentation to finally discover that it is actually quite simple.

[Read More]
macOS  Xcode 

Using CocoaPods to just build frameworks for use elsewhere

I am definitely not a fan of CocoaPods, I use Carthage in all of my projects. It is not ideal but I have a way of using it that works for me.

Recently I was faced with a problem that made me use CocoaPods but in a quite different way, just to build some frameworks to be used elsewhere without CocoaPods.

The problem

I use GRDB.swift to work with the database in iOS applications, especially because it support using SQLCipher to have the database encrypted. The current version 3.x has some problem when used by Xcode 10.2 and Swift 5 so using the latest 4.0 is recommend.

GRDB.swift never supported Carthage but there was always a way to make it work. I usually just needed to delete some of the shared schemes and run carthage build instead of carthage bootstrap. I was not able to make Carthage work with 4.0, mainly because the targets changed. There is no GRDBCipher target for use with SQLCipher anymore, just a podspec definition

  s.subspec 'SQLCipher' do |ss|
    ss.source_files = 'GRDB/**/*.swift', 'Support/*.h'
    ss.framework = 'Foundation'
    ss.dependency 'SQLCipher', '>= 3.4.0'
    ss.xcconfig = {
      'OTHER_SWIFT_FLAGS' => '$(inherited) -D SQLITE_HAS_CODEC -D GRDBCIPHER -D SQLITE_ENABLE_FTS5',
      'OTHER_CFLAGS' => '$(inherited) -DSQLITE_HAS_CODEC -DGRDBCIPHER -DSQLITE_ENABLE_FTS5',
      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SQLITE_HAS_CODEC=1 GRDBCIPHER=1 SQLITE_ENABLE_FTS5=1'
    }
end

It looks like only using CocoaPods and SwiftPM is now supported, there is not even an easy way to do manual installation.

I had to decide how to integrate 4.0 to my project in the best way possible.

[Read More]