Attributes
In addition of overriding the language/region or setting a custom user ID, you can assign attributes and tags to your users, allowing you to improve your Push targeting.
IMPORTANT
- User IDs (email address, username, etc) must be managed using our custom user ID implementation.
- Region/language data must be managed using our custom region/language implementation.
- Never use an existing tagging plan. Read our guide on custom data before tagging your app.
- Newly tracked attributes and tags are hidden by default. You will need to manually display them from the dashboard settings > "Custom data" tab.
Managing attributes
Before we get started on how to implement custom attributes, here are some rules you should know.
Naming
Attribute names are strings. They should be made of letters, numbers or underscores ([a-z0-9_]) and can't be longer than 30 characters (e.g. has_premium).
Values
Values must be any of the following types, or their native Swift equivalent:
NSString
Must not be longer than 64 characters and can be empty. For better results, you should make them upper/lowercase and trim the whitespaces.
NSNumber
- Anything bigger than a
long long
or adouble
will be rejected. - Unsigned values will be rejected.
- Booleans are supported, but should be initialized with
[NSNumber numberWithBool:<your value>]
or@YES/@NO
.
NSDate
Since timezones are not supported, this will typically represent UTC dates.
Using any unsupported type as a value (NSNull, NSObject, NSArray, NSDictionary for example) will NOT work. Be careful, as it may cause
[editor save]
to fail.
NSURL
≥ 1.18 Must not be longer than 2048 characters and must follow the format scheme://[authority][path][?query][#fragment]
.
Setting an attribute
The custom attribute API works using an editor. You need to get an instance of the editor, enqueue your changes and then call save
.
Changes will NOT be persisted until you call this method, please make sure you call it!
There is one setAttribute/set(attribute:forKey:)
method per attribute type. Use Xcode's autocompletion or see BatchUser.h
for all available variants.
If you're using Swift, the appropriate method will automatically be used according to the value's type.
Those methods throw an error if key/value failed validation according to the rules expressed higher up in this documentation.
The error status does not mean that the attributes have been sent to the the server, as it happens at a latter date.
Removing an attribute by settings its value to nil, like with pre 1.16 APIs is no longer supported.
Doing so prevents Batch from optimizing disk usage and network roundtrips, which impact your user's data plan and battery life.
Please try to batch as many operations as you can in a single transaction.
- Swift
- Objective-C
// Get a new editor instance.
// You need to save this in a local variable until you call save
// Editor instances don't share changes, and calling save on an empty editor will do nothing
let editor = BatchUser.editor()
// Set an attribute. try? allows a potential error to be silently ignored
// This example is a valid key/attribute pair, and will not throw an error.
try? editor.set(attribute: 26, forKey:"age")
do {
// Invalid attribute name, $ is a forbidden character
try editor.set(attribute: "patricia", forKey: "fir$t_name")
} catch {
// Handle the error here.
// Error is of type BatchUserDataEditorError if you want to specifically
// handle it.
}
editor.save() // Don't forget to save the changes
Please test your implementation using our debug tool before releasing your app on the store. Make sure you're unwrapping your optionals!
Legacy setAttribute
Before Batch 1.16.0, only one setAttribute
variant was available.
It takes any object for the value, and doesn't throw on validation errors.
Example:
- Swift
- Objective-C
// Deprecated in 1.16, use set(attribute:forKey:)
let editor = BatchUser.editor()
editor.setAttribute(26, forKey:"age")
editor.setAttribute(nil, forKey:"age") // Removes the attribute
editor.save() // Don't forget to save the changes
Removing one or multiple attributes
Use removeAttributeForKey
to remove one attribute and clearAttributes
to remove them all.
- Swift
- Objective-C
// Get a new editor instance.
// You need to save this in a local variable until you call save
// Editor instances don't share changes, and calling save on an empty editor will do nothing
let editor = BatchUser.editor()
editor.removeAttribute(forKey: "age") // Remove an attribute
editor.clearAttributes() // Removes all attributes
editor.save() // Don't forget to save the changes
Managing tag collections
You can attach multiple tags to different collections. Collections names can't be longer than 30 characters (e.g. favorite_categories
).
Tags have some limitations:
- They are strings.
- They will automatically be lowercased
- Their size can't be greater than 64 characters and they can't be empty.
Collection names have the same limitations as attribute names.
Here are the available methods:
- Swift
- Objective-C
// Get a new editor instance.
// You need to save this in a local variable until you call save
// Editor instances don't share changes, and calling save on an empty editor will do nothing
let editor = BatchUser.editor()
editor.addTag("has_bought", inCollection: "actions") // Add a tag to the "actions" collection
editor.removeTag("has_bought", fromCollection: "actions") // Remove it
editor.clearTagCollection("actions") // Removes all tags from that collection
// editor.clearTags() // Removes all tag collections and tags
editor.save(); // Don't forget to save the changes
Reading attributes and tag collections
Since Batch 1.14, two class methods of BatchUser
are available to asynchronously fetch saved attributes and tag collections.
Reading attributes
- Swift
- Objective-C
BatchUser.fetchAttributes { attributes in
// Attributes are retrieved in the form of a dictionary
// Values are encapsulated in an instance of BatchUserAttribute
let attribute: BatchUserAttribute = attributes["age"]
// BatchUserAttribute holds a reference to the value of the attribute
let rawValue: Any = attribute.value // Raw value is not typed
print(rawValue) // Prints "NSNumber(26)"
// The type of the value is specified via a BatchUserAttributeType enumeration
print(attribute.type) // Prints "BatchUserAttributeTypeLongLong"
// To obtain a typed result you can use one of the four helper methods
attribute.numberValue() // Will return "26" here
attribute.dateValue() // Will return nil here
attribute.stringValue() // Will return nil here
attribute.urlValue() // Will return nil here
}
Reading tag collections
- Swift
- Objective-C
BatchUser.fetchTags { tagCollections in
// Tags are also retrieved in the form of a dictionary
// Keys are names of collections, values are sets of tags
let tagCollection: Set<String> = tagCollections["actions"]
print(tagCollection) // Prints "["has_bought"]"
}
Note: Since tags are limited in size and are case sensitive, reading them back might produce different results than what had been saved.