{"_id":"588861fa165af631008ee1ff","parentDoc":null,"user":"54861b9f3681d914006992a4","__v":0,"project":"54861bb654b3ce0b00367292","version":{"_id":"588861fa165af631008ee1b8","__v":1,"project":"54861bb654b3ce0b00367292","createdAt":"2017-01-25T08:29:46.061Z","releaseDate":"2017-01-25T08:29:46.061Z","categories":["588861fa165af631008ee1b9","588861fa165af631008ee1ba","588861fa165af631008ee1bb","588861fa165af631008ee1bc","588861fa165af631008ee1bd","588861fa165af631008ee1be","588861fa165af631008ee1bf","588861fa165af631008ee1c0","588861fa165af631008ee1c1","588861fa165af631008ee1c2","588861fa165af631008ee1c3","588861fa165af631008ee1c4","588861fa165af631008ee1c5","588861fa165af631008ee1c6","588861fa165af631008ee1c7","588861fa165af631008ee1c8","588861fa165af631008ee1c9"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"5.0.0","version":"5.0"},"category":{"_id":"588861fa165af631008ee1c1","project":"54861bb654b3ce0b00367292","version":"588861fa165af631008ee1b8","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-12-08T22:54:31.828Z","from_sync":false,"order":8,"slug":"2-personalization","title":"Cases & Dynamic Objects"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2014-12-09T10:39:35.955Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"never","params":[],"url":""},"isReference":false,"order":59,"body":"**In order to apply these configurations, change the following code in your app delegate** \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions\\n  (NSDictionary *)launchOptions {\\n  [ElastiCode setAPIKey::::at:::\\\"<APIKey>\\\"]; \\n        \\n\\n  ECSessionParams* params = [ECSessionParams createInProduction:NO];\\n  // Your dynamic objects defines  \\n  [ElastiCode setSessionParams:params];\\n\\n  [ElastiCode ready];\\n  return YES;\\n}\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"class AppDelegate: UIResponder, UIApplicationDelegate {\\nvar window: UIWindow?\\n\\nfunc application(application: UIApplication, didFinishLaunchingWithOptions\\n       launchOptions: [NSObject: AnyObject]?) -> Bool {\\n   // Override point for customization after application launch.\\n   \\n    ElastiCode.setAPIKey(\\\"<APIKey>\\\")\\n    let params:ECSessionParams = ECSessionParams .createInProduction(false)\\n  // Your dynamic objects defines  \\n    ElastiCode.setSessionParams(params)\\n    ElastiCode.ready()\\n    \\n    return true\\n}\",\n      \"language\": \"swift\"\n    },\n    {\n      \"code\": \"@Override\\nprotected void onCreate(Bundle savedInstanceState) {\\n  super.onCreate(savedInstanceState);\\n  setContentView(R.layout.ac_main);\\n\\n  elasticode = Elasticode.getInstance(this, \\\"<APIKey>\\\", elasticodeObserver);\\n  ElasticodeSessionParams params = \\n    new ElasticodeSessionParams(MainActivity.this);\\n  \\n  // Your dynamic objects defines\\n  \\n  elasticode.setSessionParams(params);\\n  \\n  elasticode.ready();\\n\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n##**Defining Dynamic Objects** - Setting dashboard-controlled dynamic elements\nThe developer should define the dynamic object by:  \na) Name  \nb) Type  \nc) Default value\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Key\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description/Example\",\n    \"0-0\": \"dObjName\",\n    \"0-1\": \"String\",\n    \"0-2\": \"Naming a dynamic object. for example: \\\"Button Color\\\"\",\n    \"1-0\": \"dObjType\",\n    \"1-1\": \"ElastiCodeDObjType*\",\n    \"1-2\": \"Dynamic object type - comment below\",\n    \"2-0\": \"defaultValue\",\n    \"2-1\": \"iOS - NSObject \\n\\nSwift - AnyObject \\n\\nJava - Object\",\n    \"2-2\": \"Default value that will be used in case of an error. Relevant to the dObjType\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n* ElastiCodeDObjType has to be set as a single or multi value object (an array)\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"**iOS/Swift -** ElastiCodeDObjType_bool \\n\\n**Java -** ElastiCodeDObjType.BOOLEAN\\n\\n**Cordova -** sessionParams.ECType.bool\",\n    \"0-1\": \"**iOS** - NSNumber \\n\\n**Swift** - bool\\n\\n**Android** - Boolean\\n\\n**Cordova** - Boolean\",\n    \"0-2\": \"Boolean value, ie. true\",\n    \"h-0\": \"Key\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description/Example\",\n    \"1-0\": \"**iOS/Swift - **ElastiCodeDObjType_int\\n\\n**Java - **ElastiCodeDObjType.INTEGER\\n\\n**Cordova -** sessionParams.ECType.int\",\n    \"1-1\": \"**iOS** - NSNumber \\n\\n**Swift** - Integer\\n\\n**Android** - Integer\\n\\n**Cordova** - Integer\",\n    \"1-2\": \"Integer value, i. e. 100\",\n    \"2-0\": \"**iOS/Swift - **ElastiCodeDObjType_double\\n\\n**Java - **ElastiCodeDObjType.DOUBLE\\n\\n**Cordova -** sessionParams.ECType.double\",\n    \"2-1\": \"**iOS** - NSNumber \\n\\n**Swift** - Double\\n\\n**Android** - Double\\n\\n**Cordova** - Double\",\n    \"2-2\": \"Double value, i. e. 3.14\",\n    \"3-0\": \"**iOS/Swift - **ElastiCodeDObjType_string\\n\\n**Java - **ElastiCodeDObjType.STRING\\n\\n\\n**Cordova -** sessionParams.ECType.string\",\n    \"3-1\": \"**iOS** - NSString \\n\\n**Swift** - String\\n\\n**Android** - String\\n\\n**Cordova** - String\",\n    \"3-2\": \"String value, i.e. \\\"Welcome!\\\"\"\n  },\n  \"cols\": 3,\n  \"rows\": 4\n}\n[/block]\n##Array of\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Key\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description/Example\",\n    \"0-0\": \"**iOS/Swift - **ElastiCodeDObjType_arrayOfBool\\n\\n**Java - **ElastiCodeDObjType.ARRAY_OF_BOOLEAN\\n\\n\\n**Cordova -** sessionParams.ECType.arrayOfBool\",\n    \"0-1\": \"**iOS** - NSArray \\n\\n**Swift** - [Bool]\\n\\n**Android** - [Bool]\\n\\n**Cordova** - [Boolean]\",\n    \"0-2\": \"Boolean values ( array of  )\",\n    \"1-0\": \"**iOS/Swift - **ElastiCodeDObjType_arrayOfInt\\n\\n**Java - **ElastiCodeDObjType.ARRAY_OF_INTEGER\\n\\n\\n**Cordova -** sessionParams.ECType.arrayOfInt\",\n    \"2-0\": \"**iOS/Swift - **ElastiCodeDObjType_arrayOfDouble\\n\\n**Java - **ElastiCodeDObjType.ARRAY_OF_DOUBLE\\n\\n\\n**Cordova -** sessionParams.ECType.arrayOfDouble\",\n    \"3-0\": \"**iOS/Swift - **ElastiCodeDObjType_arrayOfString\\n\\n**Java - **ElastiCodeDObjType.ARRAY_OF_STRING\\n\\n**Cordova -** sessionParams.ECType.arrayOfString\",\n    \"1-1\": \"**iOS** - NSArray \\n\\n**Swift** - [Integer]\\n\\n**Android** - [Integer]\\n\\n**Cordova** - [Integer]\",\n    \"2-1\": \"**iOS** - NSArray \\n\\n**Swift** - [Double]\\n\\n**Android** - [Double]\\n\\n**Cordova** - [Double]\",\n    \"3-1\": \"**iOS** - NSArray \\n\\n**Swift** - [String]\\n\\n**Android** - [String]\\n\\n**Cordova** - [String]\",\n    \"1-2\": \"Integer values ( array of  )\",\n    \"2-2\": \"Double values ( array of  )\",\n    \"3-2\": \"String values ( array of  )\"\n  },\n  \"cols\": 3,\n  \"rows\": 4\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Before \\\"starting a session\\\"\",\n  \"body\": \"This method should be initiated before starting a new session\"\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[params.data defineDynamicObject:@\\\"foodTypes\\\"\\n \\ttype:ElastiCodeDObjType_arrayOfString \\n \\tdefaultValue:@[@\\\"BBQ\\\", @\\\"Healthy food\\\", @\\\"Snacks\\\"]\\n];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let foodTypes: [String] = [\\\"BBQ\\\", \\\"Healthy food\\\", \\\"Snacks\\\"]\\n \\nparams.data .defineDynamicObject(\\\"foodTypes\\\", \\n                                type: ElastiCodeDObjType_arrayOfString, \\n                                defaultValue: foodTypes)\",\n      \"language\": \"objectivec\",\n      \"name\": \"Swift\"\n    },\n    {\n      \"code\": \"params.data\\n  .defineDynamicObject(\\\"foodTypes\\\", ElasticodeDObjType.ARRAY_OF_STRING, new String[] {\\\"BBQ\\\", \\\"Healthy food\\\", \\\"Snacks\\\"});\",\n      \"language\": \"java\",\n      \"name\": \"Java\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Please note that we can use dynamic objects ONLY after sync\",\n  \"body\": \"Remember, you can only use the personalization capabilities of dynamic objects after the sync was finished.\"\n}\n[/block]\n##**Value Per Dynamic Object**\nTo use the dynamic object value, call `valueForDynamicObject` method that retrieves the relevant value. The object’s value will be set in our dashboard or set by you as default.\n\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Key\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description/Example\",\n    \"0-0\": \"dObjName\",\n    \"0-1\": \"String\",\n    \"0-2\": \"Indicate the name of the case you are defining, for example: \\\"Login button\\\"\"\n  },\n  \"cols\": 3,\n  \"rows\": 1\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"NSObject* value = [ElastiCode valueForDynamicObject:@\\\"Page Title\\\"];\\nif(value){\\n  label.text = (NSString*)value;\\n}\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let value: AnyObject? = ElastiCode .valueForDynamicObject(\\\"Page Title\\\")\\nlabel.text = value! as? NSString;\",\n      \"language\": \"objectivec\",\n      \"name\": \"Swift\"\n    },\n    {\n      \"code\": \"Object value = elasticode.valueForDynamicObject(\\\"Page Title\\\");\",\n      \"language\": \"java\",\n      \"name\": \"Java\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Optional\",\n  \"body\": \"In case you are loading the data before using it, follow these two steps:\"\n}\n[/block]\nA) Get the selected state index of a case.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"NSObject* value = [ElastiCode valueWithoutVisitForDynamicObject:@\\\"Page Title\\\"];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let value = ElastiCode .valueWithoutVisitForDynamicObject(\\\"Page Title\\\")\",\n      \"language\": \"objectivec\",\n      \"name\": \"Swift\"\n    },\n    {\n      \"code\": \"elasticode.valueWithoutVisitForDynamicObject(\\\"Page Title\\\");\",\n      \"language\": \"java\",\n      \"name\": \"Java\"\n    }\n  ]\n}\n[/block]\nB) Once a case is visible to an end user, alert our server about it:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Key\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description/Example\",\n    \"0-0\": \"dObjName\",\n    \"0-1\": \"String\",\n    \"0-2\": \"Name of the relevant object you would like to alert about\"\n  },\n  \"cols\": 3,\n  \"rows\": 1\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[ElastiCode visitDynamicObject:@\\\"Page Title\\\"];\",\n      \"language\": \"objectivec\",\n      \"name\": null\n    },\n    {\n      \"code\": \"ElastiCode .visitDynamicObject(\\\"Page Title\\\")\",\n      \"language\": \"objectivec\",\n      \"name\": \"Swift\"\n    },\n    {\n      \"code\": \"elasticode.visitDynamicObject(\\\"Page Title\\\");\",\n      \"language\": \"java\",\n      \"name\": \"Java\"\n    }\n  ]\n}\n[/block]\n##**Reaching a goal**\nIn order to optimise your app, we need to know the desired action for each dynamic object, and understand the conversion rate of each alternative.\n\nThe desired action should be defined within the code by the developer and may be a click (e.g. for the “buy\" button),\na swipe or even the fact that a user has not left the screen for 2 minutes (if you aim for retention).\n\nTo notify Elasticode regarding a successful action, use:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[ElastiCode dynamicObjectGoalReached:@\\\"Buy Button\\\"];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"ElastiCode .dynamicObjectGoalReached(\\\"Buy Button\\\")\",\n      \"language\": \"objectivec\",\n      \"name\": \"Swift\"\n    },\n    {\n      \"code\": \"elasticode.goalReached(\\\"Page Title\\\");\",\n      \"language\": \"java\",\n      \"name\": \"Java\"\n    }\n  ]\n}\n[/block]","excerpt":"Building dynamic objects and their default values, visits and actions","slug":"creating-dynamic-objects","type":"basic","title":"Creating Dynamic objects"}

Creating Dynamic objects

Building dynamic objects and their default values, visits and actions

**In order to apply these configurations, change the following code in your app delegate** [block:code] { "codes": [ { "code": "- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions\n (NSDictionary *)launchOptions {\n [ElastiCode setAPIKey:@\"<APIKey>\"]; \n \n\n ECSessionParams* params = [ECSessionParams createInProduction:NO];\n // Your dynamic objects defines \n [ElastiCode setSessionParams:params];\n\n [ElastiCode ready];\n return YES;\n}", "language": "objectivec" }, { "code": "class AppDelegate: UIResponder, UIApplicationDelegate {\nvar window: UIWindow?\n\nfunc application(application: UIApplication, didFinishLaunchingWithOptions\n launchOptions: [NSObject: AnyObject]?) -> Bool {\n // Override point for customization after application launch.\n \n ElastiCode.setAPIKey(\"<APIKey>\")\n let params:ECSessionParams = ECSessionParams .createInProduction(false)\n // Your dynamic objects defines \n ElastiCode.setSessionParams(params)\n ElastiCode.ready()\n \n return true\n}", "language": "swift" }, { "code": "@Override\nprotected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.ac_main);\n\n elasticode = Elasticode.getInstance(this, \"<APIKey>\", elasticodeObserver);\n ElasticodeSessionParams params = \n new ElasticodeSessionParams(MainActivity.this);\n \n // Your dynamic objects defines\n \n elasticode.setSessionParams(params);\n \n elasticode.ready();\n\n}", "language": "java" } ] } [/block] ##**Defining Dynamic Objects** - Setting dashboard-controlled dynamic elements The developer should define the dynamic object by: a) Name b) Type c) Default value [block:parameters] { "data": { "h-0": "Key", "h-1": "Type", "h-2": "Description/Example", "0-0": "dObjName", "0-1": "String", "0-2": "Naming a dynamic object. for example: \"Button Color\"", "1-0": "dObjType", "1-1": "ElastiCodeDObjType*", "1-2": "Dynamic object type - comment below", "2-0": "defaultValue", "2-1": "iOS - NSObject \n\nSwift - AnyObject \n\nJava - Object", "2-2": "Default value that will be used in case of an error. Relevant to the dObjType" }, "cols": 3, "rows": 3 } [/block] * ElastiCodeDObjType has to be set as a single or multi value object (an array) [block:parameters] { "data": { "0-0": "**iOS/Swift -** ElastiCodeDObjType_bool \n\n**Java -** ElastiCodeDObjType.BOOLEAN\n\n**Cordova -** sessionParams.ECType.bool", "0-1": "**iOS** - NSNumber \n\n**Swift** - bool\n\n**Android** - Boolean\n\n**Cordova** - Boolean", "0-2": "Boolean value, ie. true", "h-0": "Key", "h-1": "Type", "h-2": "Description/Example", "1-0": "**iOS/Swift - **ElastiCodeDObjType_int\n\n**Java - **ElastiCodeDObjType.INTEGER\n\n**Cordova -** sessionParams.ECType.int", "1-1": "**iOS** - NSNumber \n\n**Swift** - Integer\n\n**Android** - Integer\n\n**Cordova** - Integer", "1-2": "Integer value, i. e. 100", "2-0": "**iOS/Swift - **ElastiCodeDObjType_double\n\n**Java - **ElastiCodeDObjType.DOUBLE\n\n**Cordova -** sessionParams.ECType.double", "2-1": "**iOS** - NSNumber \n\n**Swift** - Double\n\n**Android** - Double\n\n**Cordova** - Double", "2-2": "Double value, i. e. 3.14", "3-0": "**iOS/Swift - **ElastiCodeDObjType_string\n\n**Java - **ElastiCodeDObjType.STRING\n\n\n**Cordova -** sessionParams.ECType.string", "3-1": "**iOS** - NSString \n\n**Swift** - String\n\n**Android** - String\n\n**Cordova** - String", "3-2": "String value, i.e. \"Welcome!\"" }, "cols": 3, "rows": 4 } [/block] ##Array of [block:parameters] { "data": { "h-0": "Key", "h-1": "Type", "h-2": "Description/Example", "0-0": "**iOS/Swift - **ElastiCodeDObjType_arrayOfBool\n\n**Java - **ElastiCodeDObjType.ARRAY_OF_BOOLEAN\n\n\n**Cordova -** sessionParams.ECType.arrayOfBool", "0-1": "**iOS** - NSArray \n\n**Swift** - [Bool]\n\n**Android** - [Bool]\n\n**Cordova** - [Boolean]", "0-2": "Boolean values ( array of )", "1-0": "**iOS/Swift - **ElastiCodeDObjType_arrayOfInt\n\n**Java - **ElastiCodeDObjType.ARRAY_OF_INTEGER\n\n\n**Cordova -** sessionParams.ECType.arrayOfInt", "2-0": "**iOS/Swift - **ElastiCodeDObjType_arrayOfDouble\n\n**Java - **ElastiCodeDObjType.ARRAY_OF_DOUBLE\n\n\n**Cordova -** sessionParams.ECType.arrayOfDouble", "3-0": "**iOS/Swift - **ElastiCodeDObjType_arrayOfString\n\n**Java - **ElastiCodeDObjType.ARRAY_OF_STRING\n\n**Cordova -** sessionParams.ECType.arrayOfString", "1-1": "**iOS** - NSArray \n\n**Swift** - [Integer]\n\n**Android** - [Integer]\n\n**Cordova** - [Integer]", "2-1": "**iOS** - NSArray \n\n**Swift** - [Double]\n\n**Android** - [Double]\n\n**Cordova** - [Double]", "3-1": "**iOS** - NSArray \n\n**Swift** - [String]\n\n**Android** - [String]\n\n**Cordova** - [String]", "1-2": "Integer values ( array of )", "2-2": "Double values ( array of )", "3-2": "String values ( array of )" }, "cols": 3, "rows": 4 } [/block] [block:callout] { "type": "warning", "title": "Before \"starting a session\"", "body": "This method should be initiated before starting a new session" } [/block] [block:code] { "codes": [ { "code": "[params.data defineDynamicObject:@\"foodTypes\"\n \ttype:ElastiCodeDObjType_arrayOfString \n \tdefaultValue:@[@\"BBQ\", @\"Healthy food\", @\"Snacks\"]\n];", "language": "objectivec" }, { "code": "let foodTypes: [String] = [\"BBQ\", \"Healthy food\", \"Snacks\"]\n \nparams.data .defineDynamicObject(\"foodTypes\", \n type: ElastiCodeDObjType_arrayOfString, \n defaultValue: foodTypes)", "language": "objectivec", "name": "Swift" }, { "code": "params.data\n .defineDynamicObject(\"foodTypes\", ElasticodeDObjType.ARRAY_OF_STRING, new String[] {\"BBQ\", \"Healthy food\", \"Snacks\"});", "language": "java", "name": "Java" } ] } [/block] [block:callout] { "type": "info", "title": "Please note that we can use dynamic objects ONLY after sync", "body": "Remember, you can only use the personalization capabilities of dynamic objects after the sync was finished." } [/block] ##**Value Per Dynamic Object** To use the dynamic object value, call `valueForDynamicObject` method that retrieves the relevant value. The object’s value will be set in our dashboard or set by you as default. [block:parameters] { "data": { "h-0": "Key", "h-1": "Type", "h-2": "Description/Example", "0-0": "dObjName", "0-1": "String", "0-2": "Indicate the name of the case you are defining, for example: \"Login button\"" }, "cols": 3, "rows": 1 } [/block] [block:code] { "codes": [ { "code": "NSObject* value = [ElastiCode valueForDynamicObject:@\"Page Title\"];\nif(value){\n label.text = (NSString*)value;\n}", "language": "objectivec" }, { "code": "let value: AnyObject? = ElastiCode .valueForDynamicObject(\"Page Title\")\nlabel.text = value! as? NSString;", "language": "objectivec", "name": "Swift" }, { "code": "Object value = elasticode.valueForDynamicObject(\"Page Title\");", "language": "java", "name": "Java" } ] } [/block] [block:callout] { "type": "warning", "title": "Optional", "body": "In case you are loading the data before using it, follow these two steps:" } [/block] A) Get the selected state index of a case. [block:code] { "codes": [ { "code": "NSObject* value = [ElastiCode valueWithoutVisitForDynamicObject:@\"Page Title\"];", "language": "objectivec" }, { "code": "let value = ElastiCode .valueWithoutVisitForDynamicObject(\"Page Title\")", "language": "objectivec", "name": "Swift" }, { "code": "elasticode.valueWithoutVisitForDynamicObject(\"Page Title\");", "language": "java", "name": "Java" } ] } [/block] B) Once a case is visible to an end user, alert our server about it: [block:parameters] { "data": { "h-0": "Key", "h-1": "Type", "h-2": "Description/Example", "0-0": "dObjName", "0-1": "String", "0-2": "Name of the relevant object you would like to alert about" }, "cols": 3, "rows": 1 } [/block] [block:code] { "codes": [ { "code": "[ElastiCode visitDynamicObject:@\"Page Title\"];", "language": "objectivec", "name": null }, { "code": "ElastiCode .visitDynamicObject(\"Page Title\")", "language": "objectivec", "name": "Swift" }, { "code": "elasticode.visitDynamicObject(\"Page Title\");", "language": "java", "name": "Java" } ] } [/block] ##**Reaching a goal** In order to optimise your app, we need to know the desired action for each dynamic object, and understand the conversion rate of each alternative. The desired action should be defined within the code by the developer and may be a click (e.g. for the “buy" button), a swipe or even the fact that a user has not left the screen for 2 minutes (if you aim for retention). To notify Elasticode regarding a successful action, use: [block:code] { "codes": [ { "code": "[ElastiCode dynamicObjectGoalReached:@\"Buy Button\"];", "language": "objectivec" }, { "code": "ElastiCode .dynamicObjectGoalReached(\"Buy Button\")", "language": "objectivec", "name": "Swift" }, { "code": "elasticode.goalReached(\"Page Title\");", "language": "java", "name": "Java" } ] } [/block]