Offline sync with Azure App Service - ios

I try to upgrade an objective-c project to Swift. I'm using Azure App Service with a .NET backend to store data from my mobile app (iOS) in the cloud. I just downloaded the quickstart for Swift project from the azure portal and followed the steps in the tutorial to enable offline sync functionality. However inserting an item in the table is not working. I am using the following code to store a new item in the backend
var table : MSSyncTable?
...
self.table!.insert(item) {
(result) in
let syncItem = result.0
let error = result.1
if error != nil {
print("Error: " + error!.localizedDescription)
}
...
}
Stepping through the code at runtime revealed that error is nil so everything should be working fine, but I am not getting a new entry in my table storage.
Does anybody have experience with Azure App Service and Swift and can help me with this?

Because you are using the sync table, the actual operations to send and receive data from the server are explicit. These are represented by the pushWithCompletion:error: method on the sync context (for sending data up to the cloud), and the pullWithQuery:query:queryId:completion: method on your MSSyncTable.
Note that push automatically occurs when you pull as well.
I would expect the code to look something like:
var table : MSSyncTable?
...
self.table!.insert(item) { result in
let syncItem = result.0
let error = result.1
if error != nil {
print("Error: " + error!.localizedDescription)
}
table!.pushWithCompletion() { error in
...
}
...
}

Related

Google Cloud Firestore, Swift/XCode, Creating Index Through Error Message - URL Now Missing From Error Message

I'm working on an IOS App using XCode / Swift, and Google Cloud Firestore. I will typically create new Firestore indexes by writing the Swift/Firestore code, hit the error that says "this query requires an index...click the link to create the index", and then I will follow the link to create the index via the Firebase Console.
Recently, in my development environment, I deleted several existing Firestore indexes, made some changes to the code, and then attempted to run the app. I expect the error "this query requires an index...", but I'm getting a new error that just says "no matching index found.", without the helpful link to create the index. This new error is showing up for indexes related to code that was modified, as well as for indexes related to code that I did not modify (where indexes were previously working fine).
I cannot find any documentation about what to do when the error message does not prompt to create the index, and I prefer to not create these indexes by hand through the console. Any suggestions would be greatly appreciated.
func dummyListener(completion: #escaping (Error?) -> Void) -> ListenerRegistration? {
let user_id = "12345"
let listener = db.collection("some_collection")
.order(by: "created_time")
.whereField("some_object.user_id", isEqualTo: user_id)
.addSnapshotListener {(snapshot, err) in
if let err = err {
//Throws "no matching index found" error
//Expect "this query requires an index..." url
return completion(err)
}
//...
}
return listener
}

Google Places Api Error in Swift 3

Google Places Api
I am implementing google place api in my project. I have implemented everything but google Api returns the following error:
Current Place error: The operation couldn’t be completed. An internal
error occurred in the Places API library. If you believe this error
represents a bug, please file a report using the instructions on our
community and support page
(https://developers.google.com/places/support).
It was working earlier but suddenly it stops. I found nothing in any other answer that could be helpful for me.
This my code to call the Api:
GMSPlacesClient().currentPlace(callback: {
(placeLikelihoods, error) -> Void in
guard error == nil else {
print("Current Place error: \(error!.localizedDescription)")
return
}
})
Any Help would be appreciated!!
Make sure that you have given place_id instead of id.
This solved my issue
According to the GMSPlacesClient reference (https://developers.google.com/places/ios-api/reference/interface_g_m_s_places_client) you should be accessing the shared instance of the client, so in Swift 3 your code above should be
GMSPlacesClient.shared().currentPlace(callback: {
(placeLikelihoods, error) -> Void in
guard error == nil else {
print("Current Place error: \(error!.localizedDescription)")
return
}
})

Error adding Firebase users Swift

By following the information on this link, I am currently working on trying to create a user using Firebase, as shown in the code below. However, it appears no user is created when the app is run. Any input is greatly appreciated. The Firebase URL was taken from my test database.
let ref = Firebase(url: "https://test-96df2.firebaseio.com")
ref.createUser("bobtony#example.com", password: "correcthorsebatterystaple",
withValueCompletionBlock: { error, result in
if error != nil {
// There was an error creating the account
print("error creating account")
} else {
let uid = result["uid"] as? String
print("Successfully created user account with uid: \(uid)")
}
})
Edit:
The propagated error is:
Error Code: AUTHENTICATION_DISABLED) Projects created at
console.firebase.google.com must use the new Firebase Authentication
SDKs available from firebase.google.com/docs/auth/
However, as shown below, the email/password authentication is enabled in the Firebase console.
You have already authorized the email registration as I can see in your screenshot. So the problem doesnt realies on AUTHENTICATION_DISABLED.
From your error message and the snippet code I can see that you have created a new project but you are trying to use the legacy firebase SDK and so you will have compatibility issues. Also, you are looking into the old firebase documentation.
First of all you will need to make sure you have configured your project as documented in new firebase start guide.
After, you can take a look at the documentation for creating a new user with the new sdk. You can find the 3.x create user call bellow.
FIRAuth.auth()?.createUserWithEmail(email, password: password) { (user, error) in
// ...
}

Azure Push Notification Error from IOS Xcode

I feel I am the first one in the universe trying to get iOS swift working with Azure, not much help out there.
I followed this Create an iOS app
and then Add Push Notifications to your iOS App. I am supposed to be able to do a successful push notification from iPhone, but I get this error. btw: I can get my C# code to trigger in visual studio in my pc (using this tutorial), so the request seems to be working, but the response sucks. Any one knows how to fix it!!
Error registering for notifications: Optional("Error Domain=com.Microsoft.MicrosoftAzureMobile.ErrorDomain Code=-1302 \"{\"message\":\"An error has occurred.\"}\" UserInfo={com.Microsoft.MicrosoftAzureMobile.ErrorRequestKey=<NSMutableURLRequest: 0x14cebf780> { URL: http://<mysite>.azurewebsites.net/push/installations/1E32E9B5-E976-4CCD-BD61-D026D3F4FF1C }, com.Microsoft.MicrosoftAzureMobile.ErrorResponseKey=<NSHTTPURLResponse: 0x14cec54b0> { URL: http://<mysite>.azurewebsites.net/push/installations/1E32E9B5-E976-4CCD-BD61-D026D3F4FF1C } { status code: 500, headers {\n \"Content-Length\" = 36;\n \"Content-Type\" = \"application/json; charset=utf-8\";\n Date = \"Wed, 11 May 2016 21:39:39 GMT\";\n Server = \"Microsoft-IIS/8.0\";\n \"Set-Cookie\" = \"ARRAffinity=8d79cd782ff16b44f7f280b76e2bc5564d86e0d1b228227b8e0033f4bb1c4582;Path=/;Domain=<mysite>.azurewebsites.net\";\n \"X-Powered-By\" = \"ASP.NET\";\n} }, NSLocalizedDescription={\"message\":\"An error has occurred.\"}}")
UPDATE #1
The only url I have is the one per the tutorial. The rest of the code is identical to the ones I mentioned in the links (I copied it character by character):
class ClientManager {
static let sharedClient = MSClient(applicationURLString: "http://<mysite>.azurewebsites.net")
}
UPDATE #2
#Pau Senabre I am working with swift not Objective-C per my question (see my tags under question), so I don't have an .m file per your step #1. I also don't have the logErrorIfNotNil you mentioned. My method (which is generated by Azure before modifications) looks like this:
#IBAction func addItem(sender : AnyObject) {
self.performSegueWithIdentifier("addItem", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!)
{
if segue.identifier == "addItem" {
let todoController = segue.destinationViewController as! ToDoItemViewController
todoController.delegate = self
}
}
UPDATE #3
#Pau Senabre My goal is to do mobile apps/services, not mobile engagement. See the difference here. btw: I had followed the azure engagement example when I started playing with it and had worked for me. But my need now is web/mobile apps. So, does what you suggested still apply for my need?
Could you please post some code? I think you may be using a wrong URL in a certain place.
To UPDATE #2
Check the following link:
https://github.com/Azure/azure-content/blob/master/articles/mobile-engagement/mobile-engagement-ios-swift-get-started.md
In section Modify your Application Delegate make sure you create a reach module and your existing Engagement initialization has all the init Values.
EngagementAgent.init("Endpoint={YOUR_APP_COLLECTION.DOMAIN};SdkKey={YOUR_SDK_KEY};AppId={YOUR_APPID}", modulesArray:[reach])
The error Code provided Error Domain=com.Microsoft.MicrosoftAzureMobile.ErrorDomain Code=-1302 matches to a bad request. If you are entering some data, make beforehand a Data Input Validation:
1 In the TodoService.m file, locate the addItem method search for the [self logErrorIfNotNil:error]; line of code. Beneath that line of code, replace the remainder of the completion block with the following code that checks to see if there was an error in the request and if that error code was –1302, indicating a bad request:
BOOL badRequest = ((error) && (error.code == -1302));
// detect text validation error from service.
if (!badRequest) // The service responded appropriately
{
NSUInteger index = [itemscount];
[(NSMutableArray *)itemsinsertObject:result atIndex:index];
// Let the caller know that we finished
completion(index);
}
2 Build and run; you can see in the Xcode output window that the bad request error from the service was handled:
2012-10-23 22:01:32.169 Quickstart[5932:11303] ERROR Error Domain=com.Microsoft.WindowsAzureMobileServices.ErrorDomain Code=-1302 “Text length must be under 10″ UserInfo=0x7193850 {NSLocalizedDescription=Text length must be under 10, com.Microsoft.WindowsAzureMobileServices.ErrorResponseKey=, com.Microsoft.WindowsAzureMobileServices.ErrorRequestKey=https://task.azure-mobile.net/tables/TodoItem>}
3 Finally, in the TodoService.m file, locate the logErrorIfNotNil method, which handles the logging of errors to the output window. Inside the if code block, just below the line NSLog(#”ERROR %#”, error); add the following if block:
// added to display description of bad request
if (error.code == -1302){
UIAlertView *av =
[[UIAlertView alloc]
initWithTitle:#”Request Failed”
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#”OK”
otherButtonTitles:nil
];
[av show];
}
Aditionally, review the following steps in the Azure Setup, maybe you are missing something at some point:
https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-ios-get-started-push/
1 Create a Notification Hub
This creates a new notification hub and connects it to your mobile app. If you have an existing notification hub, you can choose to connect it to your Mobile App backend instead of creating a new one.
2 Register app for push notifications
Register an App ID for your app. Create an explicit App ID (not a wildcard App ID) and for Bundle ID, use the exact Bundle ID that is in your Xcode quickstart project. It is also crucial that you check the Push Notifications option.
Next, configuring push notifications. You may create either a "Development" or "Distribution" SSL certificate (remember to select the corresponding option in the Azure portal later.)
3 Configure Azure to send push notifications
In the Azure portal, click Browse All > App Services > your Mobile App backend > Settings > Mobile > Push > Apple Push Notification Services > Upload Certificate. Upload the .p12 file, selecting the correct Mode (corresponding to whether the client SSL certificate you generated earlier was Development or Distribution.)
4 Update server project to send push notifications
Replace the PostTodoItem method with the following code:
public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
{
TodoItem current = await InsertAsync(item);
// Get the settings for the server project.
HttpConfiguration config = this.Configuration;
MobileAppSettingsDictionary settings =
this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
// Get the Notification Hubs credentials for the Mobile App.
string notificationHubName = settings.NotificationHubName;
string notificationHubConnection = settings
.Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
// Create a new Notification Hub client.
NotificationHubClient hub = NotificationHubClient
.CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
// iOS payload
var appleNotificationPayload = "{\"aps\":{\"alert\":\"" + item.Text + "\"}}";
try
{
// Send the push notification and log the results.
var result = await hub.SendAppleNativeNotificationAsync(appleNotificationPayload);
// Write the success result to the logs.
config.Services.GetTraceWriter().Info(result.State.ToString());
}
catch (System.Exception ex)
{
// Write the failure result to the logs.
config.Services.GetTraceWriter()
.Error(ex.Message, null, "Push.SendAsync Error");
}
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
this is the proper answer from another question I had earlier, which fixes both: Registration and Receiving push notifications. I said this in here:
I finally have been able to receive notifications last night. I went ahead and redid an entire walk-through of all apple-side installation steps using this tutorial: Sending push notifications to iOS with Azure Notification Hubs then the azure-side of things using this: Create an iOS app and Add Push Notifications to your iOS App. That took care of the registering the app of the device successfully, which I was able to verify using the note of AdrianHall in this thread. But that wasn't enough. The Azure tutorials fell short detailing the steps needed in Xcode, which I found here: [How To] Setup Remote Push Notification in iOS - Swift 2.0 Code I didn't have to setup any "push notification" in Xcode or anything like that.
I hope this detailed answer will save you many hours of digging through.

How to send iOS data to Azure mobile service database?

I'm new to swift and Azure and am trying to send some data from my swift app up to my azure mobile database. I have an app with CoreData working but after fetching my data i'm running into difficulties sending it up to azure. I'm trying to use the insert table method from the azure framework.
I've tried this method:
let client = MSClient(applicationURLString: "https://mymobileapp.azure-mobile.net/", applicationKey: "aAaBbBcCc…")
var client = AppDelegate().client // To reference my constant in AppDelegate.swift
var itemTable:MSTable = client.tableWithName("Item")
var itemToInsert:NSDictionary = ["text":"My Awesome Item 1"]
itemTable.insert(itemToInsert,
completion: {
insertedItem, error in
if error{
println("error: \(error)")
}
else{
println("Success!")
}
}
)
But I'm running into problems with the application key. From what I can gather, the application keys are no longer used in Azure Mobile Apps.
I've also tried the method shown in the Mobile App QuickStart guide for swift but the code seems to be for an older version of swift.
I'm not trying to display a table in my app just upload data to the database. Any help would be appreciated!
I ended up getting it to work. The application key is no longer used in the new Azure Mobile Apps. In addition to deleting the key you have to add a new property, specifically a App Transport Security property, to allow for a connection with an unsecured HTTP site.
let client = MSClient(applicationURLString: "https://mymobileapp.azure-mobile.net/")
var client = AppDelegate().client // To reference my constant in AppDelegate.swift
var itemTable:MSTable = client.tableWithName("Item")
var itemToInsert:NSDictionary = ["text":"My Awesome Item 1"]
itemTable.insert(itemToInsert,
completion: {
insertedItem, error in
if error{
print("error: \(error)")
}
else{
print("Success!")
}
}
)

Resources