(iOS) recursive vCard-temp request to the jabber server? - iphone

I am creating an iphone app with xmpframework, everything works fine, but i would like to update my profile picture with the following code. and i got some incorrect recursive vCard-temp request to the server. But the picture got updated, and notified all friends in my roster.
//I clicked on the button
-(void)updatevCardButtonClicked{
XMPPvCardTemp *vCardTemp = [[[self appDelegate] xmppvCardTempModule] myvCardTemp];
NSLog(#"my vCardTemp: %#", vCardTemp);
NSData *tempImage = [self getDataFromImage:[self resizeImage:userImage]];
[vCardTemp setPhoto: tempImage];
[[[self appDelegate] xmppvCardTempModule]updateMyvCardTemp:vCardTemp];
}
output and explanation below
my vCardTemp: *nil description*
MyApp[60625:6c1b] XMPPvCardCoreDataStorage: Triggering save (pendingRequests=0)
MyApp[60625:207] MyAppDelegate: xmppStream:didReceiveIQ: - E49C843A-5A05-4148-A4CF-B400062A83C0
MyApp[60625:207] MyAppDelegate: xmppStream:didReceivePresence: - <presence xmlns="jabber:client" from="myJabberAccount#127.0.0.1/1948110991326183732515886" to="myJabberAccount#127.0.0.1/1948110991326183732515886">
<status>At work</status>
<x xmlns="vcard-temp:x:update">
<photo>1f6401ddea76826fddc4cd7ddc17741db6c9dabc</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="></c>
<x xmlns="vcard-temp:x:update">
<photo>c3b2d65259a4fc1d37e56777697d4f5a9730fb03</photo></x><c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="></c>
</presence>
MyApp[60625:5323] XMPPRosterCoreDataStorage: handlePresence:xmppStream:
//repeat start from here, and the DidReceivePresence: will grow into tons of lines with the samthing
MyApp[60625:207] XMPPRosterCoreDataStorage: userForJID:xmppStream:managedObjectContext:
MyApp[60625:1e0b] XMPPRosterCoreDataStorage: userForJID:xmppStream:managedObjectContext:
MyApp[60625:207] XMPPRosterCoreDataStorage: resourceForJID:xmppStream:managedObjectContext:
MyApp[60625:5323] XMPPvCardCoreDataStorage: Triggering save (pendingRequests=0)
MyApp[60625:207] MyAppDelegate: xmppStream:didReceiveIQ: - (null)
MyApp[60625:1e0b] XMPPvCardCoreDataStorage: Triggering save (pendingRequests=0)
MyApp[60625:207] MyAppDelegate: xmppStream:didReceivePresence: - <presence xmlns="jabber:client" from="myJabberAccount#127.0.0.1/1948110991326183732515886" to="myJabberAccount#127.0.0.1/1948110991326183732515886">
<status>At work</status>
<x xmlns="vcard-temp:x:update">
<photo>1f6401ddea76826fddc4cd7ddc17741db6c9dabc</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="></c>
<x xmlns="vcard-temp:x:update">
<photo>c3b2d65259a4fc1d37e56777697d4f5a9730fb03</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="></c>
<x xmlns="vcard-temp:x:update">
<photo>c3b2d65259a4fc1d37e56777697d4f5a9730fb03</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4=">
</c>
</presence>
//repeat the above in the rest of the output with more and more "vcard-temp:x:update"
what i found so far, the below cause this problem, but i can't figure out where i can fix it.
//i found that these two "SEND" cause the problem, the app just keep sending these two
SEND: <iq type="get" to="myJabberAccount#127.0.0.1"><vCard xmlns="vcard-temp"/></iq>
SEND: <presence>
<x xmlns="vcard-temp:x:update">
<photo>1f6401ddea76826fddc4cd7ddc17741db6c9dabc</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="/>
<x xmlns="vcard-temp:x:update">
<photo>1f6401ddea76826fddc4cd7ddc17741db6c9dabc</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="/>
<x xmlns="vcard-temp:x:update">
<photo>f93ee3918c7baaf095edb9f6bede892c603161af</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="/>
<x xmlns="vcard-temp:x:update">
<photo>f93ee3918c7baaf095edb9f6bede892c603161af</photo>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="/>
</presence>
//this presence keep growing as you can see the repeated parts

I have been trying to tackle this problem for quite some time. Let me know if this works for you. Here's my explanation:
Whenever you send a presence element via xmppStream, it caches a copy of it under the "myPresence" instance variable.
If you look for the following method in XMPPStream.m:
- (void)continueSendElement:(NSXMLElement *)element withTag:(long)tag
there is a comment about 10-20 lines down that says:
// Update myPresence if this is a normal presence element.
// In other words, ignore presence subscription stuff, MUC room stuff, etc.
When the XMPPvCardAvatarModule class updates the vcard, it introduces things like the <x> and the <c> (capability) tags that pollutes the normal presence element.
To fix this, we need to clean up those unnecessary tags. Here is a section of my edited code:
else if ([element isKindOfClass:[XMPPPresence class]])
{
// Update myPresence if this is a normal presence element.
// In other words, ignore presence subscription stuff, MUC room stuff, etc.
XMPPPresence *presence = (XMPPPresence *)element;
// We use the built-in [presence type] which guarantees lowercase strings,
// and will return #"available" if there was no set type (as available is implicit).
NSString *type = [presence type];
if ([type isEqualToString:#"available"] || [type isEqualToString:#"unavailable"])
{
NSArray *vCardXElem = [presence elementsForName:#"x"];
NSArray *capabilitiesHash = [presence elementsForName:#"c"];
for (NSXMLElement *x in vCardXElem)
{
[presence removeChildAtIndex:[x index]];
}
for (NSXMLElement *c in capabilitiesHash)
{
[presence removeChildAtIndex:[c index]];
}
if ([presence toStr] == nil && myPresence != presence)
{
myPresence = presence;
}
}
[multicastDelegate xmppStream:self didSendPresence:(XMPPPresence *)element];
}

Related

Azure Media Services v3 create asset filter returns BadRequest

Azure Media Services v3 create asset filter returns BadRequest.
Both code and manifest are included below. Asset duration is 00:00:26.4330000
Have tried adjusting the tracks, no tracks.
Have tried adjusting the time parameters.
Any ideas on what is wrong?
Is it possible for the API to report more information on what is wrong?
Can a sample be created that shows how to use AssetFilters.CreateOrUpdate with and without track filters?
Code
var timingData = GetManifestTimingData(new Uri(asset.ManifestUrl));
Log.Info($"Timescale: {timingData.TimeScale} Offset: {timingData.TimestampOffset} clip: ( {TimeSpan.FromSeconds(startTimeSec)} - {TimeSpan.FromSeconds(endTimeSec)} ) as ( {TimeSpan.FromSeconds(startTimeSec)} to {TimeSpan.FromSeconds(endTimeSec)} ) {name} ----- {asset.ToAssetInfo()?.hashKey} {asset.Name} -- Manifest: {asset.PlaybackUrl}");
if (startTimeSec >= timingData.AssetDuration.TotalSeconds)
{
Log.Error($"Invalid start time: {startTimeSec} > {timingData.AssetDuration}");
return null;
}
if (endTimeSec >= timingData.AssetDuration.TotalSeconds)
{
endTimeSec = (int)Math.Floor(timingData.AssetDuration.TotalSeconds);
}
var startTimeSpan = timingData.OffSetAsTimeSpan + TimeSpan.FromSeconds(startTimeSec);
var endTimeSpan = timingData.OffSetAsTimeSpan + TimeSpan.FromSeconds(endTimeSec);
double timeScale = timingData.TimeScale ?? TimeSpan.TicksPerSecond;
var scaledStartTime = Convert.ToInt64(Math.Truncate(startTimeSpan.Ticks * (timeScale / TimeSpan.TicksPerSecond)));
var scaledEndTime = Convert.ToInt64(Math.Truncate(endTimeSpan.Ticks * (timeScale / TimeSpan.TicksPerSecond)));
var range = new PresentationTimeRange(scaledStartTime, scaledEndTime, 9223372036854775807, 0, (long)timeScale, false);
var tracks = new List<FilterTrackSelection>
{
new FilterTrackSelection(new List<FilterTrackPropertyCondition>
{
new FilterTrackPropertyCondition(FilterTrackPropertyType.Type, "Audio", FilterTrackPropertyCompareOperation.Equal),
}),
new FilterTrackSelection(new List<FilterTrackPropertyCondition>
{
new FilterTrackPropertyCondition(FilterTrackPropertyType.Type, "Video", FilterTrackPropertyCompareOperation.Equal),
}),
};
var firstQuality = new FirstQuality(128000);
var filterParams = new AssetFilter(null, name, FilterType, range, firstQuality, tracks);
var filter = _client.AssetFilters.CreateOrUpdate(ResourceGroup, AccountName, asset.Id, name, filterParams);
if (filter == null)
{
Log.Warn($"Failed to create filter {name} in {asset}");
return null;
}
return filter;
Manifest
<SmoothStreamingMedia MajorVersion="2" MinorVersion="2" Duration="264333333" TimeScale="10000000">
<StreamIndex Chunks="13" Type="video" Url="QualityLevels({bitrate})/Fragments(video={start time})" QualityLevels="1">
<QualityLevel Index="0" Bitrate="770760" FourCC="H264" MaxWidth="1280" MaxHeight="720" CodecPrivateData="000000016764001FACD9405005BA10000003001000000303C0F18319600000000168EBECB22C" />
<c t="0" d="20333333" r="2" />
<c d="20333334" />
<c d="20333333" r="2" />
<c d="20333334" />
<c d="20333333" r="2" />
<c d="20333334" />
<c d="20333333" r="2" />
<c d="20333334" />
<c d="20333333" />
</StreamIndex>
<StreamIndex Chunks="14" Type="audio" Url="QualityLevels({bitrate})/Fragments(aac_UND_2_127999={start time})" QualityLevels="1" Name="aac_UND_2_127999">
<QualityLevel AudioTag="255" Index="0" BitsPerSample="16" Bitrate="127999" FourCC="AACL" CodecPrivateData="1190" Channels="2" PacketSize="4" SamplingRate="48000" />
<c t="0" d="20053333" r="2" />
<c d="20053334" />
<c d="20053333" r="2" />
<c d="20053334" />
<c d="20053333" r="2" />
<c d="20053334" />
<c d="20053333" r="2" />
<c d="20053334" />
<c d="20053333" />
<c d="3626667" />
</StreamIndex>
<Protection>
<ProtectionHeader SystemID="B47B251A-2409-4B42-958E-08DBAE7B4EE9">
<ContentProtection schemeIdUri="urn:mpeg:dash:sea:2012" xmlns:sea="urn:mpeg:dash:schema:sea:2012">
<sea:SegmentEncryption schemeIdUri="urn:mpeg:dash:sea:aes128-cbc:2013" />
<sea:KeySystem keySystemUri="urn:mpeg:dash:sea:keysys:http:2013" />
<sea:CryptoPeriod IV="0xF6BCAD06C97D0FEC81B702C86183355B" keyUriTemplate="https://testurstream.keydelivery.westus.media.azure.net?kid=d6c1f008-d43f-4c60-926f-76ba613b7b4b" />
</ContentProtection>
</ProtectionHeader>
</Protection>
</SmoothStreamingMedia>
There was a known bug that we hit with Asset Filters that was fixed and rolled out to production now. Looks like you may have hit the same bug. The team is working on also fixing this issue in the .NET SDK and rolling it out.
For now, can you first delete any and all old filters created in v3 API. To fix the issue, you need to remove all old asset and global filters first from this account. We had a versioning mis-match on the filters when we moved from preview to GA that caused a mismatch (and thus the error message you are seeing.) You should be able to get a more detailed error message also if you look at the stacktrace. It typically would show a version conflict issue. Let us know what you see in the details of the error.
Carlos,
Looking at this today for you. Sorry for delay.
I'm using the Postman collection just to see what is going on with the .NET SDK exactly.
Looks like the following filer works fine. I think that the issue you are getting is related to the line of code that creates the new PresentationTimeRange. The values for presentaitonWindowDuration and liveBackoffDuration are not needed for a VOD filter. They are only used for live filters. Try using the following.
new PresentationTimeRange(scaledStartTime, scaledEndTime, null, null, (long)timeScale, null);
{
"properties": {
"presentationTimeRange": {
"startTimestamp": 0,
"endTimestamp": 264333333,
"presentationWindowDuration": null,
"liveBackoffDuration": null,
"timescale": 10000000,
"forceEndTimestamp": null
},
"tracks": [{
"trackSelections": [{
"property": "Type",
"operation": "Equal",
"value": "Video"
},
{
"property": "Type",
"operation": "Equal",
"value": "Audio"
}
]
}]
}
}
I'll double check to see if this is an issue when I run it through the .NET SDK.
I think that our issue here may be that the values for presentationTimeRange are all marked as "REQUIRED" in the current Swagger file here:
https://github.com/Azure/azure-rest-api-specs/blob/dec75495352902ebb6393d42c50465b6195f239d/specification/mediaservices/resource-manager/Microsoft.Media/stable/2018-07-01/AccountFilters.json#L63

SWXMLHash can't parse a [XMLIndexer]

I am trying for first time to parse a XML file and I am using SWXMLHash.
My xml file is:
<weatherdata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://api.met.no/weatherapi/locationforecast/1.9/schema" created="2018-02-13T18:12:31Z">
<meta>
<model name="LOCAL" termin="2018-02-13T12:00:00Z" runended="2018-02-13T14:27:32Z" nextrun="2018-02-13T22:00:00Z" from="2018-02-13T19:00:00Z" to="2018-02-16T06:00:00Z" />
<model name="EPS" termin="2018-02-13T00:00:00Z" runended="2018-02-13T09:03:05Z" nextrun="2018-02-13T22:00:00Z" from="2018-02-16T12:00:00Z" to="2018-02-22T18:00:00Z" />
</meta>
<product class="pointData">
<time datatype="forecast" from="2018-02-13T19:00:00Z" to="2018-02-13T19:00:00Z">
<location altitude="0" latitude="" longitude="">
<temperature id="TTT" unit="celsius" value="3.5"/>
<windDirection id="dd" deg="158.8" name="S"/>
<windSpeed id="ff" mps="8.8" beaufort="5" name="Frisk bris"/>
<windGust id="ff_gust" mps="15.0"/>
<areaMaxWindSpeed mps="13.8"/>
<humidity value="82.1" unit="percent"/>
<pressure id="pr" unit="hPa" value="1002.5"/>
<cloudiness id="NN" percent="99.3"/>
<fog id="FOG" percent="0.0"/>
<lowClouds id="LOW" percent="73.2"/>
<mediumClouds id="MEDIUM" percent="0.0"/>
<highClouds id="HIGH" percent="91.0"/>
<dewpointTemperature id="TD" unit="celsius" value="0.6"/>
</location>
</time>
The <time> </time> repeates.
Having made a let parsedResultXML = SWXMLHash.parse(data)
I am trying to parse with a for in loop
for node in parsedResultXML["weatherdata"]["product"]["time"].all{
print(node)
}
I get results
<time to="2018-02-14T01:00:00Z" from="2018-02-14T01:00:00Z" datatype="forecast">
<location latitude="" longitude="" altitude="0">
<temperature id="TTT" unit="celsius" value="3.4"></temperature>
<windDirection id="dd" name="S" deg="158.7"></windDirection>
<windSpeed name="Liten kuling" mps="11.1" id="ff" beaufort="6"></windSpeed>
<windGust id="ff_gust" mps="19.0"></windGust>
<areaMaxWindSpeed mps="17.5"></areaMaxWindSpeed>
<humidity unit="percent" value="88.3"></humidity>
<pressure id="pr" unit="hPa" value="1002.5"></pressure>
<cloudiness id="NN" percent="99.3"></cloudiness>
<fog id="FOG" percent="0.1"></fog>
<lowClouds id="LOW" percent="98.6"></lowClouds>
<mediumClouds id="MEDIUM" percent="93.4"></mediumClouds>
<highClouds id="HIGH" percent="57.8"></highClouds>
<dewpointTemperature id="TD" unit="celsius" value="1.5"></dewpointTemperature>
</location>
</time>
But I can't access the elements.
Using
for node in parsedResultXML["weatherdata"]["product"]["time"].all{
node["time"].element?.attribute(by: "from")?.text
}
I don't get any results back.
Any idea??
Thanks
You're close... as #rmaddy commented, node is already indexed to "time". So instead of:
for node in parsedResultXML["weatherdata"]["product"]["time"].all {
node["time"].element?.attribute(by: "from")?.text
}
Do this instead:
for node in parsedResultXML["weatherdata"]["product"]["time"].all {
node.element?.attribute(by: "from")?.text
}

How does Exchange (how can I) know that there is still a reminder pending for the last occurrence of a recurring event?

I noticed the following behavior for recurring events with reminders:
If a reminder for an occurrence is dismissed the ReminderIsSet property remains true and the ReminderDueBy property is set to the date/time of the next occurrence
When the last occurrence reminder has been dismissed ReminderIsSet still remains true and the ReminderDueBy property keeps the date/time of the last occurrence
If the last occurrence reminder is not dismissed the same happens
In that last case, in a user interface like Outlook Web Access (OWA), there is an indicator of a pending reminder:
How does Exchange, and how can I, distinguish the last two cases? How can I know that the reminder for that last occurrence was not dismissed yet?
Below is the SOAP testdata that I see querying Exchange Web Services (EWS) for two recurring appointments. They have subjects App A and App B, both were set to repeat 7 and 8 March at 12:20-12:50 CET with a 10 minute reminder:
On 8 March (=last occurrence), I dismissed the reminder for App A at 12:12, but did nothing with the reminder for App B.
If I then do GetItem calls (with BaseShape AllProperties) for both occurrences I see differences in the lines marked * at the start below. I have no idea how to conclude from this that App B still has a pending reminder. What am I missing?
Appointment A
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="1104" MinorBuildNumber="3" Version="V2_22" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
*ChangeKey <t:ItemId Id="AAMkAG[snip]AAAEA==" ChangeKey="DwAAABYAAACuuv05CWNWTKnqziXALsXrAACJ2zpT"/>
<t:ParentFolderId Id="AQMkA[snip]AAAA=" ChangeKey="AQAAAA=="/>
<t:ItemClass>IPM.Appointment.Occurrence</t:ItemClass>
* <t:Subject>App A</t:Subject>
<t:Sensitivity>Normal</t:Sensitivity>
<t:Body BodyType="Text"/>
* <t:DateTimeReceived>2016-03-08T11:06:34Z</t:DateTimeReceived>
* <t:Size>5243</t:Size>
<t:Importance>Normal</t:Importance>
<t:IsSubmitted>false</t:IsSubmitted>
<t:IsDraft>false</t:IsDraft>
<t:IsFromMe>false</t:IsFromMe>
<t:IsResend>false</t:IsResend>
<t:IsUnmodified>false</t:IsUnmodified>
* <t:DateTimeSent>2016-03-08T11:06:34Z</t:DateTimeSent>
* <t:DateTimeCreated>2016-03-08T11:06:33Z</t:DateTimeCreated>
<t:ResponseObjects>
<t:ForwardItem/>
</t:ResponseObjects>
<t:ReminderDueBy>2016-03-08T11:20:00Z</t:ReminderDueBy>
<t:ReminderIsSet>true</t:ReminderIsSet>
<t:ReminderMinutesBeforeStart>10</t:ReminderMinutesBeforeStart>
<t:DisplayCc/>
<t:DisplayTo/>
<t:HasAttachments>false</t:HasAttachments>
<t:Culture>nl-NL</t:Culture>
<t:EffectiveRights>
<t:CreateAssociated>false</t:CreateAssociated>
<t:CreateContents>false</t:CreateContents>
<t:CreateHierarchy>false</t:CreateHierarchy>
<t:Delete>true</t:Delete>
<t:Modify>true</t:Modify>
<t:Read>true</t:Read>
</t:EffectiveRights>
<t:LastModifiedName>Wendy Bakkertje</t:LastModifiedName>
* <t:LastModifiedTime>2016-03-08T11:11:56Z</t:LastModifiedTime>
<t:UID>040000[snip]CAFE1</t:UID>
<t:RecurrenceId>2016-03-08T11:20:00Z</t:RecurrenceId>
* <t:DateTimeStamp>2016-03-08T11:11:56Z</t:DateTimeStamp>
<t:Start>2016-03-08T11:20:00Z</t:Start>
<t:End>2016-03-08T11:50:00Z</t:End>
<t:OriginalStart>2016-03-08T11:20:00Z</t:OriginalStart>
<t:IsAllDayEvent>false</t:IsAllDayEvent>
<t:LegacyFreeBusyStatus>Busy</t:LegacyFreeBusyStatus>
<t:Location/>
<t:IsMeeting>false</t:IsMeeting>
<t:IsCancelled>false</t:IsCancelled>
<t:IsRecurring>true</t:IsRecurring>
<t:MeetingRequestWasSent>false</t:MeetingRequestWasSent>
<t:IsResponseRequested>true</t:IsResponseRequested>
<t:CalendarItemType>Occurrence</t:CalendarItemType>
<t:MyResponseType>Organizer</t:MyResponseType>
<t:Organizer>
<t:Mailbox>
<t:Name>Wendy Bakkertje</t:Name>
<t:EmailAddress>Wendy#tttest.nl</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Organizer>
<t:Duration>PT30M</t:Duration>
<t:TimeZone>(UTC+01:00) Amsterdam, Berlijn, Bern, Rome, Stockholm, Wenen</t:TimeZone>
<t:AppointmentSequenceNumber>0</t:AppointmentSequenceNumber>
<t:AppointmentState>0</t:AppointmentState>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
Appointment B
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="1104" MinorBuildNumber="3" Version="V2_22" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
*ChangeKey <t:ItemId Id="AAMkAG[snip]t6QAAEA==" ChangeKey="DwAAABYAAACuuv05CWNWTKnqziXALsXrAACJ2zpS"/>
<t:ParentFolderId Id="AQMkAG[snip]AAAA=" ChangeKey="AQAAAA=="/>
<t:ItemClass>IPM.Appointment.Occurrence</t:ItemClass>
* <t:Subject>App B</t:Subject>
<t:Sensitivity>Normal</t:Sensitivity>
<t:Body BodyType="Text"/>
* <t:DateTimeReceived>2016-03-08T11:07:08Z</t:DateTimeReceived>
* <t:Size>5469</t:Size>
<t:Importance>Normal</t:Importance>
<t:IsSubmitted>false</t:IsSubmitted>
<t:IsDraft>false</t:IsDraft>
<t:IsFromMe>false</t:IsFromMe>
<t:IsResend>false</t:IsResend>
<t:IsUnmodified>false</t:IsUnmodified>
* <t:DateTimeSent>2016-03-08T11:07:08Z</t:DateTimeSent>
* <t:DateTimeCreated>2016-03-08T11:07:08Z</t:DateTimeCreated>
<t:ResponseObjects>
<t:ForwardItem/>
</t:ResponseObjects>
<t:ReminderDueBy>2016-03-08T11:20:00Z</t:ReminderDueBy>
<t:ReminderIsSet>true</t:ReminderIsSet>
<t:ReminderMinutesBeforeStart>10</t:ReminderMinutesBeforeStart>
<t:DisplayCc/>
<t:DisplayTo/>
<t:HasAttachments>false</t:HasAttachments>
<t:Culture>nl-NL</t:Culture>
<t:EffectiveRights>
<t:CreateAssociated>false</t:CreateAssociated>
<t:CreateContents>false</t:CreateContents>
<t:CreateHierarchy>false</t:CreateHierarchy>
<t:Delete>true</t:Delete>
<t:Modify>true</t:Modify>
<t:Read>true</t:Read>
</t:EffectiveRights>
<t:LastModifiedName>Wendy Bakkertje</t:LastModifiedName>
* <t:LastModifiedTime>2016-03-08T11:07:08Z</t:LastModifiedTime>
* <t:UID>040000[snip]463B</t:UID>
<t:RecurrenceId>2016-03-08T11:20:00Z</t:RecurrenceId>
* <t:DateTimeStamp>2016-03-08T11:07:08Z</t:DateTimeStamp>
<t:Start>2016-03-08T11:20:00Z</t:Start>
<t:End>2016-03-08T11:50:00Z</t:End>
<t:OriginalStart>2016-03-08T11:20:00Z</t:OriginalStart>
<t:IsAllDayEvent>false</t:IsAllDayEvent>
<t:LegacyFreeBusyStatus>Busy</t:LegacyFreeBusyStatus>
<t:Location/>
<t:IsMeeting>false</t:IsMeeting>
<t:IsCancelled>false</t:IsCancelled>
<t:IsRecurring>true</t:IsRecurring>
<t:MeetingRequestWasSent>false</t:MeetingRequestWasSent>
<t:IsResponseRequested>true</t:IsResponseRequested>
<t:CalendarItemType>Occurrence</t:CalendarItemType>
<t:MyResponseType>Organizer</t:MyResponseType>
<t:Organizer>
<t:Mailbox>
<t:Name>Wendy Bakkertje</t:Name>
<t:EmailAddress>Wendy#tttest.nl</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Organizer>
<t:Duration>PT30M</t:Duration>
<t:TimeZone>(UTC+01:00) Amsterdam, Berlijn, Bern, Rome, Stockholm, Wenen</t:TimeZone>
<t:AppointmentSequenceNumber>0</t:AppointmentSequenceNumber>
<t:AppointmentState>0</t:AppointmentState>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
The Logic that is used for reminders is documented in https://msdn.microsoft.com/en-us/library/ee219839(v=exchg.80).aspx its relative complex and you'll need to use the extended properties to implement it fully. The other thing you can use in 2013 and up is EWS has a reminders operation https://msdn.microsoft.com/en-us/library/office/dn720424(v=exchg.150).aspx but Mapi clients like Outlook use the Reminders Search Folder in the Non_IPM_Subtree
Cheers
Glen

How to Parse XML File using xmlparsing on iphone?

How do I access following XML file using xmlparsing on an iphone?
<?xml version="1.0" encoding="iso-8859-1"?>
<chapter>
<TITLE>Title &plainEntity;</TITLE>
<para>
<informaltable>
<tgroup cols="3">
<tbody>
<row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
<row><entry>a2<<?xml version="1.0" encoding="iso-8859-1"?>
<ADDRESS>
<CONTACT>
<NAME FIRST="Fred" LAST="Bloggs" NICK="Bloggsie" TITLE="Mr" />
<STREET HOME="5 Any Street" WORK="Floor 24, BigShot Tower" />
<CITY HOME="Little Town" WORK="Anycity" />
<COUNTY HOME="Anyshire" WORK="Anyshire" />
<POSTAL HOME="as plain text" WORK="text" />
<COUNTRY HOME="UK" WORK="UK" />
<PHONE HOME="as text" WORK="text" />
<FAX HOME="none" WORK="555" />
<MOBILE HOME="444" WORK="333" />
<WEB HOME="www.codehelp.co.uk" WORK="" />
<COMPANY>Full name of company here</COMPANY>
<GENDER>male</GENDER>
<BDAY>Add tags for year, month and day to make this more useful</BDAY>
<ANNI>some date long forgotten :-)</ANNI>
<SPOUSE>angry</SPOUSE>
<CHILDREN>Make sure this tag is one of the ones allowed to repeat in the DTD</CHILDREN>
<COMMENT>comments here</COMMENT>
<EMAILONE>Either use fixed tags like this, or change to a repeating tag</EMAILONE>
<EMAILTWO>second email line</EMAILTWO>
<EMAILTHREE>third</EMAILTHREE>
<EMAILFOUR>fourth</EMAILFOUR>
</CONTACT>
</ADDRESS>/entry><entry>c2</entry></row>
<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
&systemEntity;
<section id="about">
<title>About this Document</title>
<para>
<!-- this is a comment -->
</para>
</section>
</chapter>
The SDK provides two ways to parse XML: libxml2 and NSXMLParser. libxml2 is the fastest. To use it in your project, go to the build settings for your iPhone App project and set the following:
Other linker flags = -lxml2
Header Search Paths: $(SDKROOT)/usr/include/libxml2
Then download XPathQuery.m and XPathQuery.h from this page: Using libxml2 for XML parsing and XPath queries in Cocoa, which also provides a tutorial on how to use it. That XPathQuery class is a simplified way to parse XML. I recommend it unless you want to write the same code yourself, which doesn't seem the case.
With that on place, do
NSString *string = nil; // put your html document here
NSData *htmlData = [string dataUsingEncoding:NSUTF8StringEncoding];
NSString *xpath = #"//row"; // any standard XPath expression
NSArray *nodesArray = PerformHTMLXPathQuery(htmlData, xpath);
NSDictionary *dict;
if (0<[nodesArray count]) {
dict = [nodesArray objectAtIndex:0];
}
At this point the elements from your document should be inside the dict dictionary.
Here are releated the SO post,
Parser XML with NSXMLParser
http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project
NSXMLParser example
below is the blog tutorial for using NSXMLParser.
http://markstruzinski.com/?p=47

suds: incorrect marshaling of Array of Arrays

I try to talk to a load balancer (Zeus ZXTM) with python:
a = client.factory.create('StringArrayArray')
b = client.factory.create('StringArray')
b.value = ['node01:80',]
a.value = [b,]
client.service.addDrainingNodes(['my pool'], a)
But I get the following error:
suds.WebFault: Server raised fault: 'Not an ARRAY reference at /usr/local/zeus/zxtmadmin/lib/perl/Zeus/ZXTM/SOAPBase.pm line 772.
Extract of the schema definition:
<types>
<xsd:schema targetNamespace='http://soap.zeus.com/zxtm/1.0/'
xmlns='http://www.w3.org/2001/XMLSchema'
xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'>
<xsd:complexType name="StringArray">
<xsd:complexContent>
<xsd:restriction base='SOAP-ENC:Array'>
<xsd:attribute ref='SOAP-ENC:arrayType' wsdl:arrayType='xsd:string[]'/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="StringArrayArray">
<xsd:complexContent>
<xsd:restriction base='SOAP-ENC:Array'>
<xsd:attribute ref='SOAP-ENC:arrayType' wsdl:arrayType='zeusns:StringArray[]'/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
</types>
<message name="addDrainingNodesRequest">
<part name="names" type="zeusns:StringArray" />
<part name="values" type="zeusns:StringArrayArray" />
</message>
<message name="addDrainingNodesResponse"></message>
<portType name="PoolPort">
<operation name="addDrainingNodes">
<documentation>
Add nodes to the lists of draining nodes, for each of the named pools.
</documentation>
<input message="zeusns:addDrainingNodesRequest"/>
<output message="zeusns:addDrainingNodesResponse"/>
</operation>
</portType>
</definitions>
I also tried like this:
client.service.addDrainingNodes(['my pool'], [['node01:80']])
which worked in SOAPpy but now in suds I get:
suds.WebFault: Server raised fault: 'Value isn't an array'
Comparison between what SOAPpy and what suds sends:
SOAPpy (works):
<ns1:addDrainingNodes xmlns:ns1="http://soap.zeus.com/zxtm/1.0/Pool/" SOAP-ENC:root="1">
<v1 SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array">
<item>my pool</item>
</v1>
<v2 SOAP-ENC:arrayType="xsd:list[1]" xsi:type="SOAP-ENC:Array">
<item SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array">
<item>node01:80</item>
</item>
</v2>
</ns1:addDrainingNodes>
suds (doesn't work):
<ns4:addDrainingNodes>
<names xsi:type="ns0:StringArray" ns3:arrayType="ns2:string[1]">
<item xsi:type="ns2:string">my pool</item>
</names>
<values xsi:type="ns0:StringArrayArray" ns3:arrayType="ns0:StringArray[1]">
<item xsi:type="ns2:string">node01:80</item>
</values>
</ns4:addDrainingNodes>
Context:
I'm new to suds and Soap
there's only the SOAP interface to the ZXTM loadbalancer
using python2.6 and suds 0.3.9
we used to use ZSI's SOAPpy, but had issues using it under python 2.6
Edit: Added suds/SOAPpy payloads
After trying
zillions of different arguments to this function
wsdl2py from ZSI
I found out that suds 4.0 offers plugins, that solves this case by hacking, but nonetheless I think that's a suds bug:
class FixArrayPlugin(Plugin):
def sending(self, context):
command = context.envelope.getChild('Body').getChildren()[0].name
if command == 'addDrainingNodes':
context.envelope.addPrefix('xsd', 'http://www.w3.org/1999/XMLSchema')
values = context.envelope.getChild('Body').getChild('addDrainingNodes').getChild('values')
values.set('SOAP-ENC:arrayType', 'xsd:list[1]')
values.set('xsi:type', 'SOAP-ENC:Array')
item = values[0]
item.set('SOAP-ENC:arrayType', 'xsd:list[1]')
item.set('xsi:type', 'SOAP-ENC:Array')
client = Client(wsdl, location=location, plugins=[FixArrayPlugin()])
a = client.factory.create('StringArrayArray')
b = client.factory.create('StringArray')
b.item = ['node01:80']
a.item = [b,]
client.service.addDrainingNodes(['my pool'], a)
I'm looking forward for this issue to be fixed, IMO this should be a one liner
I'm leaving this open as I'm still interested in better alternatives
What looks strange to me is you have to explicitly construct types like 'StringArrayArray' and 'StringArray' - a smart enough SOAP client in a language like python should be able to figure this out via reflection, examining the arguments you pass to the service call. I'm guessing they're declared in the wsdl as something like "SOAP-ENC:Array" - if so they're not intended to be objects. That would also make sense with the error message "Not an ARRAY reference". Have you tried just;
a = [ ['node01:80',], ]
client.service.addDrainingNodes(['my pool'], a)
Or failing that perhaps...
a = client.factory.create('StringArrayArray')
b = ['node01:80',]
a.value = [ b, ]
client.service.addDrainingNodes(['my pool'], a)
Good luck.