A Framework that gives you access to the powerful Mesosfer cloud platform from your iOS app. For more information about Mesosfer and the features, see Mesosfer Website and Mesosfer Documentations.
[Mesosfer initializeWithApplicationId: @"YOUR-APPLICATION-ID"
clientKey: @"YOUR-CLIENT-KEY"]
Mesosfer.initialize(withApplicationId: "YOUR-APPLICATION-ID",
clientKey: "YOUR-CLIENT-KEY")
(Optional) You can add some custom setup :
Mesosfer provides a specialized bucket User that automatically handles much of the functionality required for user management. With this bucket, you’ll be able to manage user account functionality in your app.
The first thing your app will do is probably ask the user to register. The following code illustrates a typical register:
// create new instance of Mesosfer User
MFUser *user = [MFUser user];
// set default field
user.email = @"user.one@mesosfer.com";
user.password = @"user1234";
user.firstname = @"User";
user.lastname = @"One";
// set custom field
user["dateOfBirth"] = [NSDate date];
user["height"] = @177.5;
user["weight"] = @78;
user["isMarried"] = @YES;
user["myObject"] = [NSDictionary dictionary];
user["myArray"] = [NSArray array];
// execute register user asynchronous
[user registerAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// register succeeded
} else {
// register failed, show error message
}
}
// create new instance of Mesosfer User
let user = MFUser()
// set default field
user.email = "user.one@mesosfer.com"
user.password = "user1234"
user.firstname = "User"
user.lastname = "One"
// set custom field
user["dateOfBirth"] = NSDate()
user["height"] = 177.5
user["weight"] = 78
user["isMarried"] = true
user["myObject"] = [String:AnyObject]()
user["myArray"] = [[String:AnyObject]]()
// execute register user asynchronous
user.registerAsync { (succeeded, error) in
if succeeded {
// register succeeded
} else {
// register failed, show error message
}
}
This call will
If a register isn’t successful, you should read the
After you allow users to register, you need be able to let them log in to their account in the future. To do this you can use several method for handling action in login process.
It would be bothersome if the user had to login every time they open your app. You can avoid this by using the cached
Whenever you use any
MFUser *user = [MFUser currentUser];
if (user) {
// user logged in, open main view
} else {
// session not found, open login view
}
if let user = MFUser.currentUser() {
// user logged in, open main view
} else {
// session not found, open login view
}
After you allow users to register, you need be able to let them login to their account in the future. To do this, you can use the class method
[MFUser logInAsyncWithEmail:@"username@mail.com"
password:@"myPlainPassword"
block:^(MFUser * _Nullable user, NSError * _Nullable error) {
if (error) {
// error happen, show error message
return;
}
// log in succeeded
}];
MFUser.logInAsync(withEmail: "myUsername",
password: "myPlainPassword") { (user, error) in
if let e = error as? NSError {
// error happen, show error message
return
}
// log in succeeded
}
You can clear the current user by logging them out:
[MFUser logOutAsyncWithBlock:^(NSError * _Nullable error) {
if (error) {
// error happen, show error message
return;
}
// log out succeeded
}];
}
MFUser.logOutAsync { (error) in
if let e = error as? NSError {
// error happend, show error message
return
}
// log out succeeded
}
Mesosfer allow you to retreive current user attributes and update all of them.
If you need to fetch data on a current user with the latest data that is in the cloud, you can call the fetchAsync method like so:
MFUser *user = [MFUser currentUser];
[user fetchAsyncWithBlock:^(MFUser * _Nullable user, NSError * _Nullable error) {
if (error) {
// error happen, show error message
return;
}
// fetch user data succeeded
}];
let user = MFUser.currentUser()
user.fetchAsync { (user, error) in
if let e = error as? NSError {
// error happen, show error message
return
}
// fetch user data succeeded
}
This will automatically update
After logged in, you can update your data that stored in cloud using method
MFUser *user = [MFUser currentUser];
// set default field
user.firstname = @"Updated firstname";
user.lastname = @"Updated lastname";
// set custom field
user[@"dateOfBirth"] = [NSDate date];
user[@"height"] = @177.5;
user[@"weight"] = @78;
user[@"isMarried"] = @YES;
// execute update user
[user saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// update succeeded
} else {
// update failed, show error message
}
}];
let user = MFUser()
// set default field
user.firstname = "Updated firstname"
user.lastname = "Updated lastname"
// set custom field
user["dateOfBirth"] = NSDate()
user["height"] = 177.5
user["weight"] = 78
user["isMarried"] = true
// execute update user
user.saveAsync { (succeeded, error) in
if succeeded {
// update succeeded
} else {
// update failed, show error message
}
}
If you want to change your current password, use method
MFUser *user = [MFUser currentUser];
[user changePasswordAsyncWithOldPassword:@"oldPassword"
newPassword:@"newPassword"
block:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// password changed successfully
} else {
// error happen, show error message
}
}];
let user = MFUser.currentUser()
user.changePasswordAsync(withOldPassword: oldPassword,
newPassword: newPassword, block: { (succeeded, error) in
if succeeded {
// password changed successfully
} else {
// error happen, show error message
}
})
Mesosfer allow you to retreive users data using special query. There are serveral types of Mesosfer Query : Basic Query, Query Constraint, and Query on String, and Counting.
In many cases, there is a condition that need to specify which users you want to retrieve. The
MFQuery *query = [MFUser query];
[query whereKey:@"firstname" equalTo:@"John"];
[query findAsyncWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if (error) {
// error happen, show error message
return;
}
// users found, display result in table view
}];
let query = MFUser.query()
query.whereKey("firstname", equalTo: "John");
findAsync { (users, error) in
if let e = error as? NSError {
// error happen, show error message
return
}
// users found, display result in table view
}
There are several ways to put constraints on the objects found by a
[query whereKey:@"firstname" notEqualTo:@"John"];
query.whereKey("firstname", notEqualTo: "John")
You can give multiple constraints, and users will only be in the results if they match all of the constraints. In other words, it’s like an AND of constraints.
[query whereKey:@"firstname" notEqualTo:@"John"];
[query whereKey:@"height" greaterThan:@170];
query.whereKey("firstname", notEqualTo: "John")
query.whereKey("height", greaterThan: 170)
You can limit the number of results with
[query setLimit:20]; // limit to at most 20 results
query.setLimit(20) // limit to at most 20 results
You can skip the first results with
[query setSkip:10]; // skip the first 10 results
query.setSkip(10) // skip the first 10 results
For sortable types like numbers and strings, you can control the order in which results are returned:
// Sorts the results in ascending order by the user height
[query orderByAscending:@"height"];
// Sorts the results in descending order by the user height
[query orderByDescending:@"height"];
// Sorts the results in ascending order by the user height
query.order(byAscending: "height")
// Sorts the results in descending order by the user height
query.order(byDescending: "height")
You can add more sort keys to the query as follows:
// Sorts the results in ascending order by the user height field if the previous sort keys are equal.
[query addAscendingOrder:@"height"];
// Sorts the results in descending order by the user weight field if the previous sort keys are equal.
[query addDescendingOrder:@"weight"];
// Sorts the results in ascending order by the user height field if the previous sort keys are equal.
query.addAscendingOrder("height")
// Sorts the results in descending order by the user weight field if the previous sort keys are equal.
query.addDescendingOrder("weight")
For sortable types, you can also use comparisons in queries:
// Restricts to height < 170
[query whereKey:@"height" lessThan:@170];
// Restricts to height <= 170
[query whereKey:@"height" lessThanOrEqualTo:@170];
// Restricts to height > 170
[query whereKey:@"height" greaterThan:@170];
// Restricts to height >= 170
[query whereKey:@"height" greaterThanOrEqualTo:@170];
// Restricts to height < 170
query.whereKey("height", lessThan: 170)
// Restricts to height <= 170
query.whereKey("height", lessThanOrEqualTo: 170)
// Restricts to height > 170
query.whereKey("height", greaterThan: 170)
// Restricts to height >= 170
query.whereKey("height", greaterThanOrEqualTo: 170)
Use
// Finds user email that start with 'john'.
MFQuery *query = [MFUser query];
[query whereKey:@"email" hasPrefix:@"john"];
// Finds user email that start with 'john'.
let query = MFUser.query()
query.whereKey("email", hasPrefix: "john")
The example above will match any
Use
// Finds user email that end with '@okmail.com'.
MFQuery *query = [MFUser query];
[query whereKey:@"email" hasSuffix: @"@okmail.com"];
// Finds user email that end with '@okmail.com'.
let query = MFUser.query()
query.whereKey("email", hasSuffix: "@okmail.com")
The example above will match any
If you just need to count how many objects match a query, but you do not need to retrieve all the objects that match, you can use
MFQuery *query = [MFUser query];
[query whereKey:@"height" greaterThan:@170];
[query countAsyncWithBlock:^(int number, NSError * _Nullable error) {
if (error) {
// error happen, show error message
return;
}
// counting users succeeded, show result
}];
let query = MFUser.query()
query.whereKey("height", greaterThan: 170)
query.countAsync { (count, error) in
if let e = error as? NSError {
// error happen, show error message
return
}
// counting users succeeded, show result
}
Storing data on Mesosfer is built around the
For example, let's say you set a Beacon parameters. A single
"isActive":true, "major":1, "name":"Beacon One", "minor":284, "proximityUUID":"CB10023F-A318-3394-4199-A8730C7C1AEC"
Keys must be alphanumeric strings. Values can be
Let’s say you want to save the Beacon described above to the Mesosfer Cloud. The interface is similar to a Map, plus the
MFData *data = [MFData dataWithBucket:@"Beacon"];
// set data
data[@"name"] = @"Beacon One";
data[@"proximityUUID"] = @"CB10023F-A318-3394-4199-A8730C7C1AEC";
data[@"major"] = @1;
data[@"minor"] = @284;
data[@"isActive"] = @YES;
data[@"timestamp"] = [NSDate date];
// execute save data
[data saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// data saved, show success message
} else {
// failed to save data, show error message
}
}];
let data = MFData(withBucket: "Beacon")
// set data
data["name"] = "Beacon One"
data["proximityUUID"] = "CB10023F-A318-3394-4199-A8730C7C1AEC"
data["major"] = 1
data["minor"] = 284
data["isActive"] = true
data["timestamp"] = NSDate()
// execute save data
data.saveAsync { (succeeded, error) in
if succeeded {
// data saved, show success message
} else {
// failed to save data, show error message
}
}
If you need to fetch a data with the latest data that is in the cloud, you can call the
// create data from existing objecId
MFData *data = [MFData dataWithObjectId:@"objectId"];
// fetching the data
[data fetchAsyncWithBlock:^(MFData * _Nullable data, NSError * _Nullable error) {
if (error) {
// data failed to fetch, show error message
return;
}
// data fetched
}];
// create data from existing objecId
let data = MFData(withObjectId: "objectId")
// fetching the data
data.fetchAsync { (data, error) in
if let e = error as? NSError {
// data failed to fetch, show error message
return
}
// data fetched
}
This will automatically update data with the latest data from cloud.
There are many other ways to retrieve data with Mesosfer Query. You can retrieve many data at once, put conditions on the data you wish to retrieve.
In many cases, there is a condition that need to specify which
MFQuery *query = [MFData queryWithBucket:@"Beacon"];
[query whereKey:@"name" equalTo:@"Beacon One"];
[query findAsyncWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if (error) {
// error happen, show error message
return;
}
// data beacon's found, display result in table view
}];
let query = MFData.query(withBucket: "Beacon")
query.whereKey("name", equalTo: "Beacon One")
query.findAsync(block: { (datas, error) in
if let e = error as? NSError {
// error happen, show error message
return
}
// data beacon's found, show the result
})
There are several ways to put constraints on the datas found by a
[query whereKey:@"name" notEqualTo:@"Beacon One"];
query.whereKey("name", notEqualTo: "Beacon One")
You can give multiple constraints, and datas will only be in the results if they match all of the constraints. In other words, it’s like an AND of constraints.
[query whereKey:@"name" notEqualTo:@"Beacon One"];
[query whereKey:@"major" greaterThan:@1];
query.whereKey("name", notEqualTo: "Beacon One")
query.whereKey("major", greaterThan: 1)
You can limit the number of results with
[query setLimit:20]; // limit to at most 20 result
query.setLimit(20) // limit to at most 20 results
You can skip the first results with
[query setSkip:10]; // skip the first 10 results
query.setSkip(10) // skip the first 10 results
For sortable types like numbers and strings, you can control the order in which results are returned:
// Sorts the results in ascending order by the beacon's major
[query orderByAscending:@"major"];
// Sorts the results in descending order by the beacon's minor
[query orderByDescending:@"minor"];
// Sorts the results in ascending order by the beacon's major
query.order(byAscending: "major")
// Sorts the results in descending order by the beacon's minor
query.order(byDescending: "minor")
You can add more sort keys to the query as follows:
// Sorts the results in ascending order by the beacon's major field if the previous sort keys are equal.
[query addAscendingOrder:@"major"];
// Sorts the results in descending order by the beacon's minor field if the previous sort keys are equal.
[query addDescendingOrder:@"minor"];
// Sorts the results in ascending order by the beacon's major field if the previous sort keys are equal.
query.addAscendingOrder("major")
// Sorts the results in descending order by the beacon's minor field if the previous sort keys are equal.
query.addDescendingOrder("minor")
For sortable types, you can also use comparisons in queries:
// Restricts to major < 123
[query whereKey:@"major" lessThan:@123];
// Restricts to major <= 123
[query whereKey:@"major" lessThanOrEqualTo:@123];
// Restricts to major > 123
[query whereKey:@"major" greaterThan:@123];
// Restricts to major >= 123
[query whereKey:@"major" greaterThanOrEqualTo:@123];
// Restricts to major < 123
query.whereKey("major", lessThan: 123)
// Restricts to major <= 123
query.whereKey("major", lessThanOrEqualTo: 123)
// Restricts to major > 123
query.whereKey("major", greaterThan: 123)
// Restricts to major >= 123
query.whereKey("major", greaterThanOrEqualTo: 123)
Use
// Finds beacon's name that start with 'Beacon'.
MFData *query = [MFData queryWithBucket:@"Beacon"];
[query whereKey:@"name" hasPrefix:@"Beacon"];
// Finds beacon's name that start with 'Beacon'.
let query = MFData.query(withBucket: "Beacon")
query.whereKey("name", hasPrefix: "Beacon")
The example above will match any
Use
// Finds beacon's name that end with 'One'.
MFData *query = [MFData queryWithBucket:@"Beacon"];
[query whereKey:@"name" hasSuffix:@"One"];
// Finds beacon's name that end with 'One'.
let query = MFData.query(withBucket: "Beacon")
query.whereKey("name", hasSuffix: "One")
The example above will match any
If you only need to count how many datas match a query, but you do not need to retrieve all the datas that match, you can use
MFData *query = [MFData queryWithBucket:@"Beacon"];
[query whereKey:@"major" greaterThan:@123];
[query countAsyncWithBlock:^(int number, NSError * _Nullable error) {
if (error) {
// error happen, show error message
return;
}
// counting data beacon's succeeded, show result number
}];
let query = MFData.query(withBucket: "Beacon")
query.whereKey("major", greaterThan: 123)
query.countAsync { (count, error) in
if let e = error as? NSError {
// error happen, show error message
return
}
// counting data beacon's succeeded, show result
})
After getting the data, you can update your data that stored in cloud using method
MFData *data; // fetched data
// set data
data[@"name"] = @"Beacon Two";
data[@"proximityUUID"] = @"CB10023F-A318-3394-4199-A8730C7C1AEC";
data[@"major"] = @2;
data[@"minor"] = @284;
data[@"isActive"] = @NO;
data[@"timestamp"] = [NSDate date];
// execute save data
[data saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// data updated, show success message
} else {
// failed to update data, show error message
}
}];
MFData data // fetched data
// set data
data["name"] = "Beacon Two"
data["proximityUUID"] = "CB10023F-A318-3394-4199-A8730C7C1AEC"
data["major"] = 2
data["minor"] = 284
data["isActive"] = false
data["timestamp"] = NSDate()
// execute save data
data.saveAsync { (succeeded, error) in
if succeeded {
// data updated, show success message
} else {
// failed to update data, show error message
}
}
To delete a data from the Mesosfer Cloud, use method
[data deleteAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// data deleted, show success message
} else {
// failed to delete data, show error message
}
}];
data.deleteAsync { (succeeded, error) in
if succeeded {
// data deleted, show success message
} else {
// failed to delete data, show error message
}
}