====== Migration Guide ====== ===== The version System ===== We use a three-level versioning system for SDK releases. The three-level versioning system guarantees backward compatibility between siblings in the second and third levels of release numbers in the form M.X.Y. A variation in the third level of the version number (Y in the example above) indicates that only bug fixes and security patches have been included, so compatibility between siblings is guaranteed. Variation in the second level (X in the example above) indicates that new methods and functionalities have been added, and that old methods or accessors may have been deprecated. Deprecation warnings are expected in these releases. In the main level of version number (M in this case), we remove the previously announced deprecated functions and clean up the code, so binary compatibility with previous releases is not guaranteed. This Versioning system starts in V3. ===== Migrating to V3 ===== One of the main features added to the V3 release is support to configure the SDK via external configuration files. The original method of setting the SDK up via code is still supported. This support is different on iOS and in Android, as the SDK uses the recommended approach for each platform (.plists in iOS and a new XML file in Android). ==== iOS ==== === Deprecated functions and classes === \\ == Class UnstoredIncomingMessage == In SDK V3 we've deprecated the class **UnstoredIncomingMessage** in favor of the new **Message** class. This new class simplifies the handling of Push notifications arriving to the SDK instance. The new Message class has the exact same fields used by our [[https://www.messangi.com/documentation/doku.php?id=restapi:push_retrieve#retrieving_pending_push_messages|REST API]]. The attributes of this new class are: String blastID String id String type String from String to String subject String text String status String statusDescription String date String timezone String clientId String appName String platform String metadata The Method available from this class are - (id) init; - (NSDictionary *) toDictionary; - (BOOL) save; - (BOOL) delete; + (NSArray *) getAllMessages; + (NSArray *) getAllSortedMessages; So you can retrieve all Messages stored in the device, and save, update or delete a single message in a simpler way. Please refer to the REST API Documentation for more information. == Function messageLoadFinishedReturningMessage == This function has been deprecated in favor of **pushReceived:(Message)message**, using the new Message class and replicating the same functionality already present in the Android version of the SDK. == Configuring the Messangi SDK programmatically == The traditional method for initializing the Messangi SDK is still supported by adding the SDK credentials directly in the code inside the **AppDelegate**'s **didFinishLaunchingWithOptions** method: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; ... [[Messangi sharedInstance] setAppName: @"..."]; [[Messangi sharedInstance] setClientID: @"..."]; [[Messangi sharedInstance] setApiClientPrivateKey: @"..."]; [[Messangi sharedInstance] setSubscriptionInstanceID:@"..."]; [[Messangi sharedInstance] setSubscriptionURL:@"...."]; [[Messangi sharedInstance] initSubscriptions]; [[Messangi sharedInstance] initMessangi]; [[Messangi sharedInstance] registerDialog]; ... return YES; } == Configuring the Messangi SDK via config files == You can now create a configuration file to store the SDK credentials, allowing an easy transition from Development to Production while testing the app: == 1. Create the Config Files == * in xCode click on the lower left corner "+" sign * Click in "File..." option * In the newly opened window select "Property List" in the Type of Files section. Add the name of the new file * Now need add these **Properties** = Required = name: appName type: String Description: The appName provided by Ogangi name: clientID type: String Description: The cliendID provided by Ogangi name: apiClientPrivateKey type: String Description: The privateKey provided by Ogangi = Optional for subscriptions = name: subscriptionURL type: String Description: The subscription URL provided by Ogangi Default value: null name: subscriptionInstanceID type: String Description: The workspace ID provided by Ogangi Default value: null = Optional for the Environment = name: maxStoredMessages type: Number Description: The max number of messages to be stored in device, 0 for not limit Default value: 0 name: analyticsDisabled type: Boolean Description: Send Analytic info to the BI platform Default value: false name: locationDisabled type: Boolean Description: Use location of the device (Geopush, Geofence, Beacon won't work if disabled) Default value: false name: LoggingDisabled type: Boolean Description: Show debug information of the SDK in the console Default value: false The optional fields for subscriptions and environment can be stored in different files if needed. == 2. Add this code to the didFinishLaunchingWithOptions function in your AppDelegate == [[Messangi sharedInstance] loadMessangiCredentials:@""]; [[Messangi sharedInstance] loadSubscriptionsFromFile:@""]; [[Messangi sharedInstance] loadEnvironmentFromFile:@""]; Example: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [[Messangi sharedInstance] loadMessangiCredentials:@"messangiCredentials"]; [[Messangi sharedInstance] loadSubscriptionsFromFile:@"messangiSubscriptionList"]; [[Messangi sharedInstance] loadEnvironmentFromFile:@"messangiProperties"]; [[Messangi sharedInstance] initSubscriptions]; [[Messangi sharedInstance] initMessangi]; [[Messangi sharedInstance] registerDialog]; return YES; } ==== Android ==== === Support for Android 6 (API Level 23) === Starting in **Android 6**, Android introduces a new permissions model where users can now directly manage app permissions at runtime. Users can grant or revoke permissions individually for installed apps. To handle these permissions within your app you need override the function **onRequestPermissionsResult** on the app's **MainActivity**: @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { ... } The Messangi SDK adds a new function in the Messangi Instance to handle internal permissions needed by the SDK. This function needs to be called inside the previous overridden function. @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { try { Messangi.getInstance().onRequestPermissionsResult(requestCode,permissions,grantResults); } catch (Exception e) { e.printStackTrace(); } } This is required to successfully **support Android 6 and later**. === Configuring the Messangi SDK programmatically === The traditional way to configure the Messangi SDK by adding the custom credentials to the **onCreate** function in the app's **MainActivity** is still supported: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Messangi Credentials Messangi.getInstance().setAppName("..."); Messangi.getInstance().setApiClientPrivateKey("..."); Messangi.getInstance().setClientId("..."); // GCM Credentials Messangi.getInstance().setGcmApiKey("..."); Messangi.getInstance().setGcmProjectId("..."); // Subscription manager Messangi.getInstance().setSubscriptionURL("..."); Messangi.getInstance().setSubscriptionInstanceId("..."); Messangi.getInstance().init(this); Messangi.getInstance().addMessangiListener(this); Messangi.getInstance().registerDialog(this, this); } === Configuring the Messangi SDK via config files === Now you can create a configuration file to include the SDK settings, allowing for an easy transition from Development to Production during the development proces: == 1. Create the Config Files == * In androidStudio right click on some folder inside the main "res" folder * Select New > XML Resource file * Enter the name for the XML file in the New File window * Add the properties: = Required = name: messangi_app_name type: string Description: The appName provided by Ogangi name: client_id type: string Description: The cliendID provided by Ogangi name: api_client_private_key type: string Description: The privateKey provided by Ogangi name: gcm_api_key type: string Description: This api key is provided by Google when you create the credentials for push notifications name: gcm_project_id type: string Description: This Project ID is provided by Google when you create the credentials for push notifications = Optional for subscriptions = name: subscription_url type: string Description: The subscription URL provided by Ogangi Default value: null name: subscription_id type: string Description: The workspace ID provided by Ogangi Default value: null = Optional for the Environment = name: max_stored_messages type: integer Description: The max number of messages to be stored in device, 0 for not limit Default value: 0 name: analytics_allowed type: bool Description: Send Analytics info to the BI platform Default value: true name: location_allowed type: bool Description: Use the device's location services (Geopush, Geofence, Beacon won't work) Default value: true name: logging_allowed type: bool Description: Show debug information of the SDK in the console Default value: true Example: Messangi wzuuzVeVA4hR9Xc8kWQB D79BFFVx2TjXcJrrnktB AIzaSyDoThF8Mbagpnt4sDUy5ENf-GwfbU4zoEc 554154250704 {base_url}/rest/api 8 true true true 15 The optional fields for subscriptions and environment can be stored in difference files if needed. == 2. Add this code to the onCreate function in your MainActivity == Messangi.getInstance().loadCredentials(this); Messangi.getInstance().loadSubscriptionCredentials(this); Messangi.getInstance().loadEnvironment(this); Example: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Messangi.getInstance().loadCredentials(this); Messangi.getInstance().loadSubscriptionCredentials(this); Messangi.getInstance().loadEnvironment(this); Messangi.getInstance().init(this); Messangi.getInstance().addMessangiListener(this); Messangi.getInstance().registerDialog(this, this); }