Our iOS create registration was working fine till last week and is failing now with the following error:
<Error xmlns:i="http://www.w3.org/2001/XMLSchema-instance">__<Code>400</Code><Detail>Failed to parse RegistrationDescription Expected text/cdata.__TrackingId:4e7f1f5b-7a17-4b92-a204-892847751234,TimeStamp:5/16/2023 9:51:44 AM +00:00</Detail></Error>
So now we have a broken app that can no longer register to notification hub.
Is this something that changed on the hub side or Can we proceed with the workaround with no further issues on registration and notifications?
Note as a workaround, we are able to successfully create the registration through REST.
When we remove CDATA syntax, the registration to the notification hub succeeds.
Workaround:
<BodyTemplate>\n {\"aps\":{\"alert\":{\"title-loc-key\":\"$(notification_title)\",\"loc-key\":\"$(notification_message)\"}},\"sound\":\"default\",\"content-available\":\"1\",\"message_owner\":\"$(message_owner)\", \"token\":\"$(token)\", \"user\":\"$(user)\"}\n </BodyTemplate>\n
iOS Template is same as the template provided in Azure documentation:
NSString *XML_RegStr = @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry xmlns=\"http://www.w3.org/2005/Atom\">\n <content type=\"application/xml\">\n <AppleTemplateRegistrationDescription xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.microsoft.com/netservices/2010/10/servicebus/connect\">\n <Tags>%@</Tags>\n <DeviceToken>%@</DeviceToken>\n <BodyTemplate>\n <![CDATA[{\"aps\":{\"alert\":{\"title-loc-key\":\"$(notification_title)\",\"loc-key\":\"$(notification_message)\"}},\"sound\":\"default\",\"content-available\":\"1\",\"message_owner\":\"$(message_owner)\", \"token\":\"$(token)\", \"user\":\"$(user)\"}]]>\n </BodyTemplate>\n </AppleTemplateRegistrationDescription>\n </content>\n</entry>";
Hello @Lakshmi Subramanya ,
I hope the answer provided by @Sedat SALMAN helps. Please let me know if you have any further queries.
Please accept as Yes if the answer provided is useful, so that you can help others in the community looking for remediation for similar issues.
Result of the possible errors:
Check the XML encoding: Yes both Content-type header and XML declaration matches, header contains uff-8 —> @"Content-Type": @"application/atom+xml;type=entry;charset=utf-8"
Validate the XML structure:
Note, from our application we register a device through 2 ways:
Using WindowsAzureMessaging.framework APIs
Result: Success with the same template
Using REST API with the same template wrapped inside CDATA block
Result: Failed to parse RegistrationDescription Expected text/cdata.
After removing CDATA format from xml string and performing REST call, I get CREATE_REG success and also the REST response contains CDATA format which was not included in the request.
Request: <BodyTemplate>\n {\"aps\":{\"alert\":\"$(message)\"}}\n </BodyTemplate>\n
Response: <BodyTemplate><![CDATA[
{"aps":{"alert":"$(message)"}}
Escape special characters: Non-alphanumeric characters used are quotes, $, colon, {, }, (, ), underscore _, hyphen - and comma. Quotes are escaped everywhere in our template.
Test with a minimal template: I tried with the basic message “{“aps”:{“alert”:”$(message)”}}” by escaping quotes, still the same CDATA error.
When I manipulated data, I get “Failed to parse BodyTemplate: Invalid template payload” error and not CDATA error.
Validate the Azure Notification Hub configuration: What configuration on Azure notification hub could affect the parsing of registration template?
he error message you're encountering, "Failed to parse RegistrationDescription Expected text/cdata," suggests that there is an issue with the CDATA syntax in your iOS template registration for Azure Notification Hub. The CDATA section is used to enclose text that contains special characters, ensuring that they are not treated as markup by the parser. In your case, it seems that the CDATA section is causing a problem during parsing.
To proceed with a workaround, you have already identified that removing the CDATA syntax allows the registration to succeed. However, please note that removing the CDATA section means that any special characters within the template will not be handled correctly. So if your template contains any special characters, removing the CDATA section might result in unexpected behavior or incorrect rendering of the notification content.
To address the issue and still preserve the CDATA section, you can try the following steps:
Check the XML encoding: Ensure that the XML encoding specified in the Content-Type header and the XML declaration (<?xml version="1.0" encoding="utf-8"?>) matches. In your case, the encoding is set to UTF-8, so verify that the header and the declaration both specify the same encoding.
Validate the XML structure: Ensure that the XML structure of your template registration is correct. Verify that all elements and tags are properly nested and closed.
Escape special characters: If your template contains special characters, make sure they are properly escaped within the CDATA section. For example, characters like <, >, &, or quotes (") should be replaced with their corresponding XML entities (<, >, &, ").
Test with a minimal template: Try simplifying your template to the minimum required for registration, and gradually add complexity to identify if a specific part of the template is causing the issue. This will help isolate the problem and identify any specific characters or syntax that might be causing the parsing error.
Validate the Azure Notification Hub configuration: Double-check your Notification Hub configuration to ensure there haven't been any recent changes that could affect the parsing of the registration template. Review the template requirements and ensure that your configuration aligns with the specified guidelines.
Result of the possible errors:
Check the XML encoding: Yes both Content-type header and XML declaration matches, header contains uff-8 —> @"Content-Type": @"application/atom+xml;type=entry;charset=utf-8"
Validate the XML structure:
Note, from our application we register a device through 2 ways:
Using WindowsAzureMessaging.framework APIs
Result: Success with the same template
Using REST API with the same template wrapped inside CDATA block
Result: Failed to parse RegistrationDescription Expected text/cdata.
After removing CDATA format from xml string and performing REST call, I get CREATE_REG success and also the REST response contains CDATA format which was not included in the request.
Request: <BodyTemplate>\n {\"aps\":{\"alert\":\"$(message)\"}}\n </BodyTemplate>\n
Response: <BodyTemplate><![CDATA[
{"aps":{"alert":"$(message)"}}
Escape special characters: Non-alphanumeric characters used are quotes, $, colon, {, }, (, ), underscore _, hyphen - and comma. Quotes are escaped everywhere in our template.
Test with a minimal template: I tried with the basic message “{“aps”:{“alert”:”$(message)”}}” by escaping quotes, still the same CDATA error.
When I manipulated data, I get “Failed to parse BodyTemplate: Invalid template payload” error and not CDATA error.
Validate the Azure Notification Hub configuration: What configuration on Azure notification hub could affect the parsing of registration template?
The detailed analysis you've done is comprehensive.
Looking at the information you've provided, here are some additional considerations:
Ensure that your HTTP request's 'Content-Type' header is set to 'application/atom+xml;type=entry;charset=utf-8' and also ensure the XML encoding in the first line of your XML is set to utf-8. Both these settings need to be in place as they indicate to the server how to interpret the request body.
Since you're using the Apple Push Notification service (APNs), verify that the format of your template matches the payload expected by APNs
Given that removing the CDATA allows successful registration and the server responds back with a CDATA in the body template, it does seem like a discrepancy on the Azure Notification Hub side. If you've verified all these steps and the issue persists, I'd recommend reaching out to Azure support directly
Headers, Content-type, XML encoding are all in place. Also template matches the payload expected by APNs.
Still the issue persists. I appreciate your suggestions very much. I am discussing this issue with support now.
I was able to find one more workaround/solution based on the suggestion provided by Apple engineer in https://developer.apple.com/forums/thread/22964.
On using low level libxml2 API, created CDATA format xml node and the response is in following format, with which template registration is successful.
Azure documentation format: <BodyTemplate><![CDATA[{Template for the body}]]></BodyTemplate>
iOS native API CDATA format: <
BodyTemplate encoding=\"CDATA\">
I am checking now if change in template format has any issue at Azure end. Also in first place, why this issue occurred at released build.
HTTP Content-Type, XML encoding are all in place. Template matches the APNs payload format.
I appreciate your suggestions very much. I am discussing this issue with support.
However, I found one more solution/workaround suggested by Apple engineer in the forum, https://developer.apple.com/forums/thread/22964
Using low level libxml2 API, I was able to create CDATA format xml node, with which template registration is successful.
Azure documentation format: <BodyTemplate><![CDATA[{Template for the body}]]></BodyTemplate>
iOS native API CDATA format: <
BodyTemplate encoding=\"CDATA\">
Now I am contacting support team to understand why the issue occurred all of sudden in release build? Also will new iOS CDATA encoding format has any issue in parsing from their end.
Solution: The space between the "<BodyTemplate>" and "<![CDATA[>" format was leading to the issue 400 - Bad request.
Error:
<BodyTemplate>
<![CDATA[{Template for the body}]]>
</BodyTemplate>
On removing the space and sending the request with no new line character and tab space, the request was successful.
Solution:
<BodyTemplate><![CDATA[{Template for the body}]]></BodyTemplate>