IOS Targets for each client

2019-08-04 02:34发布

问题:

A little background:

In android we have developed the same app, basically we have developed the Android app first now we have created its IOS version, so there are multiple clients of this app. In android we are really handling this situation using Android modules system.

Now in IOS we have to do same thing. And that is to make the samecode base to be use in for multiple clients.

I did research and found the Targets and framework are the best option. I created the workspace added the framework and added the projects. But it all going in trouble for no reason.

So I decided to move onto targets. So I read and its easy to understand but can it satisfy my following requirements

  1. Separate swift file for each target. (I have a common file which contains URL links and other things, that is needed different for each client, so can I make same file per client having change the urls and other things
  2. App icons (there must be separate icons for each targets )
  3. Colors off app (I want different color for each client. Here I really do not know how to do this, because I have given Colors to app using IB)
  4. FCM and its file "GoogleService-Info.plist" (how it should be managed for multiple targets )

Update: This is How I am coding in App Delegate

    import Firebase
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let gcmMessageIDKey = "gcm.message_id"

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        FirebaseApp.configure()

        // [START set_messaging_delegate]
        Messaging.messaging().delegate = self
        // [END set_messaging_delegate]
        // Register for remote notifications. This shows a permission dialog on first run, to
        // show the dialog at a more appropriate time move this registration accordingly.
        // [START register_for_notifications]
        if #available(iOS 10.0, *) {
            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.current().delegate = self

            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()

        // [END register_for_notifications]
        return true
    }

    // [START receive_message]
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
        // If you are receiving a notification message while your app is in the background,
        // this callback will not be fired till the user taps on the notification launching the application.
        // TODO: Handle data of notification
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

        // Print full message.
        print(userInfo)
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // If you are receiving a notification message while your app is in the background,
        // this callback will not be fired till the user taps on the notification launching the application.
        // TODO: Handle data of notification
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

        // Print full message.
        print(userInfo)

        completionHandler(UIBackgroundFetchResult.newData)
    }

Please tell is it achievable using "Targets" and how?

回答1:

1. When you create target all files added till then will be available to the newly created target. Then for every new file you add you can choose the target for that file. You can change that preference in target membership section in file inspector.

2. You can have different app icon for different targets

  1. Create a different app icon in Assets
  2. Then set the newly created app icon in target -> App icon section.

3. For different color:

You can set compile flags for each target

Locate Swift compiler flags in the target build settings under Swift Compiler — Custom Flags → Other Swift Flags

Created flag in other swift flags will help to distinguish between the target. Then Depending upon the value give color like this

#if TARGET1

let fillColor       = UIColor(red: 30/255.0, green: 100/255.0, blue: 100/255.0, alpha: 1.0)
let fillColorWithAlpha  = UIColor(red: 30/255.0, green: 100/255.0, blue: 100/255.0, alpha: 0.9)

let buttonColor     = UIColor(red: 15/255.0, green: 45/255.0, blue: 90/255.0, alpha: 1.0)
let buttonColorDeselected = UIColor(red: 100/255, green: 100/255, blue: 100/255, alpha: 1.0)



#else
let fillColor       = UIColor(red: 74/255.0, green: 144/255.0, blue: 226/255.0, alpha: 1.0)
let fillColorWithAlpha       = UIColor(red: 74/255.0, green: 144/255.0, blue: 226/255.0, alpha: 0.9)

let buttonColor     = UIColor(red: 36/255.0, green: 97/255.0, blue: 168/255.0, alpha: 1.0)
let buttonColorDeselected = UIColor(red: 116/255, green: 116/255, blue: 116/255, alpha: 1.0)



#endif 

Where "TARGET1" is the value you have given in swift flag section.

Lastly Use this fillColor that you configured to change the Color. For Example to set background color of UIButton to that color -> Create custom class and give the color that you have configured for different target. By doing this you can just change the color in configuration rather than updating the entire UI

class CustomThemeButton: UIButton {


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setBackGroundColor()
    }

    required override init(frame: CGRect) {
        super.init(frame: frame)
        setBackGroundColor()
    }

    private func setBackGroundColor(){

        self.backgroundColor = fillColor
    }

}