#c# #php #objective-c #decode
#c# #php #objective-c #декодировать
Вопрос:
Я работаю над Objective C
приложением, которое получает GPS-маршруты с сервера. Маршруты закодированы, и у меня есть сценарии декодирования, написанные на обоих PHP
языках и C#
.
Насколько мне известно, там невозможно скомпилировать или импортировать скрипт в проект Xcode.
Я приложил два приведенных ниже сценария вместе с копией закодированного маршрута GPS.
Я довольно много изучил сценарий и понимаю (по большей части), что происходит.) Возможно ли перенести этот код на Objective C
? Если да, то какой подход был бы наилучшим? И как бы я перенес byte streams
?
Я немного сбит с толку, так как я никогда раньше не работал с кодированием / декодированием, но любая помощь высоко ценится.
Закодированный маршрут GPS
BANZ1OIkuAAAAAAAAAAAAAAAJAP S1s5CQxSBwAiljQJ/8//RgIsBA7bAjQF//r/MQQsBPjSAjQP/6//RAIsAvjbAjQR/6j/PgAsB8q2ACwI75D LAXow/4sBd2V/iwLnZcANA7/cf9y/iwKnpH NCX/g/9s/DQP/4T/bvw0C/ 1/3H8LArVqPwsBPPO/iwC/foANBX/tf9U DQY/2z/nPw0F//X/zjqNBL/wP8 6CwE 9P6LBkhxvo0Ev9U/6XyLAWtFgI0I/9 AB4CLAfKKwQ0Gv9nAHAELATdFQAsBdIcAiwQkEn8LATgFf4sD6kj CwUjFr6NAb/ gCfBiwN7 j LAcdhf4sAQ3vADQM/ T/Q/AsAu/l/DQK/7r/c 4sDd2E9CwIwbn0NAX/dP v6jQR/4n/augsCcCP CwG0N36LAHzAP40Gv w/1b0LAv2u/4sBN3i/CwQu6X2LBEOigA0LP/z/0z NBYAJP84GjQcAH7/eR4sA//iAjQXABj/TRY0Hf/Q/1EONB8AP/9KGDQVAIb/fho0GACP/4oQLBFtogosAx7NBDQNAKD/lw4sCHngDCwGLcQGLAEN8wIsBTTMCCwDAdMCLAc5swosBCPhBCwCCvoALA9howwsCUO1CDQLAKH/pggsAyvYADQIAHz/XAQsAiDiAiwFMvcALAMd9wIsBgPEAjQTAAX/KAo0BwAp/yv2LATli/osAwPb/jQJAF7/OAY0CQBB/0EINA4Acf9RDiwHDqMGLAnmrgY0EP/G/0EMLAfhqQQsBP3RBCwGGKMOLAUmwwwsAQDyAiwJH6IQLAIX9wQsCVsPDCwFFisANBQAhACLAjQMAFIAxvQsAQoKACwFLywCNA8AfACBADQUAJQAhgQsClNhADQJALUAOw4sCEpIBjQPAJ4AZBIsCFokDCwJaZUOLAEG9wA0KQCM/ MSNBwAeQCMDDQQAHr/XxA0JACX/7cSLAQd5AQsBAfUAiwEG94CNBH/ /83BiwCBvAANCAAgP/QDCwgPHkCLAgEXf40HP/0AMD6LAIRHQIsB RM/CwBAAj LAztefwsC/Z7/jQTAEkAtAIsBAMxADQS/ EAjvwsB9FV/CwJ V/ NBUACwDL/CwB wcALCEMX/4sBPQ9/jQa/6gAofY0CP/fAMf4LAbMXvYsIUg5AjQKALn/1xAsAhH AiwFMvsENB0Aqf/cDiwbaKEMLBuxGfosBu9M jQT/5YApOwsFLOpADQH/24AIvQsBpAq8iwD vkANBIArv oFiwIScIKLAZEoQosB2m/CCwBBfwCNCcAswAEDDQOAK//vQYsB34W/CwEEA/ NA0Awf/s iwFQhj8NAkAgf/G/iwDLQX NBQAuf//ADQOALkAARYsBTUVBjQkAIIACw4sBT4CCCwEJO4GLAIY gIsB1IfCDQWALMARRIsBToJBCwfZEgKLAPoJ/wsA oa/CwM5lD LATjGvwsAu/ /jQO/08AQuwsAuAJ/CwIqCP2LAa DfgsA/ID/jQV/3cAfOw0G/ iAJbwLAXZfPY0Df ALjyNBT/jACe7jQT/8YAvfgsBMr/ACwD1NoALAmVvQAsAf/ ADQaAIsAif40CAAZANn4LAYLafwsA Yp/CwD5xH LATlJf4sA/Yb/iwF8yj8LBpBJQAsAh3 AiwDKR4ANBAAagCM/iwFJQECNBMAugAkDiwGTTYELAMVJQAsClwbBjQlAIQAdQQ0GwCbAFYKNBYApwA6DDQPAKwAWAQsBELlCCwBAgAANBb/xgDS6jQI/8wAhPIsBdk2 CwMtGTyNBUADADF8DQV/8QAwuw0EP/fAL/2LAMlLAA0CQC6AAUKLAlYCgYsB0YMBjQPAML/0hIsAQ3/AiwJZfEKNA0AsQBTCiwCFAQCLAED/wA0CgCgAHIKNAsAlwB8CCwHRUIELAdgBgosCWYvCCwJVy4INAoAgwBoCCwDJREANAoAnQCCADQHAEsAzfo0DAB0AKH NAsAqQBzAjQGAHgAov40DQB6AJ/ NAgAnQCGACwDPCQANA4AngAyAiwEYhQANAgAxQAABDQIALwACQI0CAC4/98GLARE3AQsBVknAjQHAJEAkAI0Bv/wAN36NAX/ gDV jQF//8A4PY0BgAGAOr0NAb/6wDd/DQH/ YA0fo0Bf/oAPb NAP/ wCS/CwDAjT8NMoAGgEF9jQx/8T/YwQ0GAAr/zgMLAUP4AA=
C # сценарий декодирования
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
// Classes for managing IOF XML 3.0 Route element.
// IOF XML 3.0 specification: http://code.google.com/p/iofdatastandard/source/browse/trunk/IOF.xsd.
// IOF XML 3.0 example result list file with Route element: http://code.google.com/p/iofdatastandard/source/browse/trunk/Examples/ResultList1.xml.
/// <summary>
/// Class representing a route, including logic for converting to/from an IOF XML 3.0 route stored in binary format.
/// </summary>
public class IofXml30Route
{
private double? length;
private IEnumerable<IofXml30Waypoint> waypoints = new List<IofXml30Waypoint>();
/// <summary>
/// The waypoints of the route.
/// </summary>
public IEnumerable<IofXml30Waypoint> Waypoints
{
get { return waypoints; }
set { waypoints = value ?? new List<IofXml30Waypoint>(); }
}
/// <summary>
/// Writes the route in IOF XML 3.0 binary format to the specified stream.
/// </summary>
/// <param name="stream">The stream to write to.</param>
public void WriteToStream(Stream stream)
{
IofXml30Waypoint previousWaypoint = null;
foreach (var waypoint in Waypoints)
{
waypoint.WriteToStream(stream, previousWaypoint);
previousWaypoint = waypoint;
}
}
/// <summary>
/// Converts the route to IOF XML 3.0 binary format and returns it as a base64-encoded string.
/// </summary>
/// <param name="formattingOptions">The formatting options for the base64-encoded string.</param>
public string ToBase64String(Base64FormattingOptions formattingOptions = Base64FormattingOptions.None)
{
return Convert.ToBase64String(ToByteArray(), formattingOptions);
}
/// <summary>
/// Converts the route to IOF XML 3.0 binary format and returns it as a byte array.
/// </summary>
public byte[] ToByteArray()
{
using (var ms = new MemoryStream())
{
WriteToStream(ms);
return ms.ToArray();
}
}
/// <summary>
/// Reads a route in IOF XML 3.0 binary format from a stream.
/// </summary>
/// <param name="stream">The stream to read from.</param>
public static IofXml30Route FromStream(Stream stream)
{
var waypoints = new List<IofXml30Waypoint>();
while (stream.Position < stream.Length)
{
waypoints.Add(IofXml30Waypoint.FromStream(stream, waypoints.LastOrDefault()));
}
return new IofXml30Route() { Waypoints = waypoints };
}
/// <summary>
/// Reads a route in IOF XML 3.0 binary format from a base64-encoded string.
/// </summary>
/// <param name="base64String">The base64-encoded string to read from.</param>
public static IofXml30Route FromBase64String(string base64String)
{
return FromByteArray(Convert.FromBase64String(base64String));
}
/// <summary>
/// Reads a route in IOF XML 3.0 binary format from a byte array.
/// </summary>
/// <param name="bytes">The bytes to read from.</param>
public static IofXml30Route FromByteArray(byte[] bytes)
{
using (var ms = new MemoryStream(bytes))
{
return FromStream(ms);
}
}
/// <summary>
/// Gets the length of the route in meters.
/// </summary>
public double Length
{
get { return length ?? (length = CalculateLength()).Value; }
}
/// <summary>
/// Gets the start time of the route.
/// </summary>
public DateTime StartTime
{
get { return Waypoints.Any() ? Waypoints.First().Time : DateTime.MinValue; }
}
/// <summary>
/// Gets the end time of the route.
/// </summary>
public DateTime EndTime
{
get { return Waypoints.Any() ? Waypoints.Last().Time : DateTime.MinValue; }
}
/// <summary>
/// Gets the duration of the route.
/// </summary>
public TimeSpan Duration
{
get { return EndTime - StartTime; }
}
private double CalculateLength()
{
var sum = 0.0;
var wpList = Waypoints.ToList();
for(var i=1; i<Waypoints.Count(); i )
{
sum = GetDistanceBetweenWaypoints(wpList[i - 1], wpList[i]);
}
return sum;
}
private static double GetDistanceBetweenWaypoints(IofXml30Waypoint w1, IofXml30Waypoint w2)
{
// use spherical coordinates: rho, phi, theta
const double rho = 6378200; // earth radius in metres
double sinPhi0 = Math.Sin(0.5 * Math.PI w1.Latitude / 180.0 * Math.PI);
double cosPhi0 = Math.Cos(0.5 * Math.PI w1.Latitude / 180.0 * Math.PI);
double sinTheta0 = Math.Sin(w1.Longitude / 180.0 * Math.PI);
double cosTheta0 = Math.Cos(w1.Longitude / 180.0 * Math.PI);
double sinPhi1 = Math.Sin(0.5 * Math.PI w2.Latitude / 180.0 * Math.PI);
double cosPhi1 = Math.Cos(0.5 * Math.PI w2.Latitude / 180.0 * Math.PI);
double sinTheta1 = Math.Sin(w2.Longitude / 180.0 * Math.PI);
double cosTheta1 = Math.Cos(w2.Longitude / 180.0 * Math.PI);
var x1 = rho * sinPhi0 * cosTheta0;
var y1 = rho * sinPhi0 * sinTheta0;
var z1 = rho * cosPhi0;
var x2 = rho * sinPhi1 * cosTheta1;
var y2 = rho * sinPhi1 * sinTheta1;
var z2 = rho * cosPhi1;
return DistancePointToPoint(x1, y1, z1, x2, y2, z2);
}
private static double DistancePointToPoint(double x1, double y1, double z1, double x2, double y2, double z2)
{
var sum = (x2 - x1)*(x2 - x1) (y2 - y1)*(y2 - y1) (z2 - z1)*(z2 - z1);
return Math.Sqrt(sum);
}
}
/// <summary>
/// Class representing a waypoint, including logic for converting to/from an IOF XML 3.0 waypoint stored in binary format.
/// </summary>
public class IofXml30Waypoint
{
private static readonly DateTime zeroTime = new DateTime(1900, 01, 01, 00, 00, 00, DateTimeKind.Utc);
private const long timeSecondsThreshold = 255;
private const long timeMillisecondsThreshold = 65535;
private const int lanLngBigDeltaLowerThreshold = -32768;
private const int lanLngBigDeltaUpperThreshold = 32767;
private const int lanLngSmallDeltaLowerThreshold = -128;
private const int lanLngSmallDeltaUpperThreshold = 127;
private const int altitudeDeltaLowerThreshold = -128;
private const int altitudeDeltaUpperThreshold = 127;
/// <summary>
/// Gets or sets the type of the waypoint; normal or interruption.
/// </summary>
public IofXml30WaypointType Type { get; set; }
/// <summary>
/// Gets or sets the time when the waypoint was recorded.
/// </summary>
public DateTime Time { get; set; }
/// <summary>
/// Gets or sets the latitude of the waypoint.
/// </summary>
public double Latitude { get; set; }
/// <summary>
/// Gets or sets the longitude of the waypoint.
/// </summary>
public double Longitude { get; set; }
/// <summary>
/// Gets or sets the altitude of the waypoint.
/// </summary>
public double? Altitude { get; set; }
/// <summary>
/// Gets or sets the the time when the waypoint was recorded in the internal storage mode.
/// </summary>
public ulong StorageTime
{
get { return (ulong)Math.Round((Time - zeroTime).TotalMilliseconds); }
set { Time = zeroTime.AddMilliseconds(value); }
}
/// <summary>
/// Gets or sets the latitude of the waypoint in the internal storage mode.
/// </summary>
public int StorageLatitude
{
get { return (int)Math.Round(Latitude * 1000000); }
set { Latitude = (double)value / 1000000; }
}
/// <summary>
/// Gets or sets the longitude of the waypoint in the internal storage mode.
/// </summary>
public int StorageLongitude
{
get { return (int)Math.Round(Longitude * 1000000); }
set { Longitude = (double)value / 1000000; }
}
/// <summary>
/// Gets or sets the altitude of the waypoint in the internal storage mode.
/// </summary>
public int? StorageAltitude
{
get { return Altitude == null ? (int?)null : (int)Math.Round(Altitude.Value * 10); }
set { Altitude = value == null ? (double?)null : (double)value / 10; }
}
/// <summary>
/// Writes the waypoint in IOF XML 3.0 binary format to a stream.
/// </summary>
/// <param name="stream">The stream to write to.</param>
/// <param name="previousWaypoint">The previous waypoint of the route, or null if this is the first waypoint.</param>
public void WriteToStream(Stream stream, IofXml30Waypoint previousWaypoint)
{
var timeStorageMode = TimeStorageMode.Full;
if (previousWaypoint != null)
{
if ((StorageTime - previousWaypoint.StorageTime) % 1000 == 0 amp;amp; (StorageTime - previousWaypoint.StorageTime) / 1000 <= timeSecondsThreshold)
{
timeStorageMode = TimeStorageMode.Seconds;
}
else if (StorageTime - previousWaypoint.StorageTime <= timeMillisecondsThreshold)
{
timeStorageMode = TimeStorageMode.Milliseconds;
}
}
var positionStorageMode = PositionStorageMode.Full;
if (previousWaypoint != null amp;amp;
(StorageAltitude == null || (previousWaypoint.StorageAltitude != null amp;amp; StorageAltitude - previousWaypoint.StorageAltitude >= altitudeDeltaLowerThreshold amp;amp; StorageAltitude - previousWaypoint.StorageAltitude <= altitudeDeltaUpperThreshold)))
{
if (StorageLatitude - previousWaypoint.StorageLatitude >= lanLngSmallDeltaLowerThreshold amp;amp; StorageLatitude - previousWaypoint.StorageLatitude <= lanLngSmallDeltaUpperThreshold amp;amp;
StorageLongitude - previousWaypoint.StorageLongitude >= lanLngSmallDeltaLowerThreshold amp;amp; StorageLongitude - previousWaypoint.StorageLongitude <= lanLngSmallDeltaUpperThreshold)
{
positionStorageMode = PositionStorageMode.SmallDelta;
}
else if (StorageLatitude - previousWaypoint.StorageLatitude >= lanLngBigDeltaLowerThreshold amp;amp; StorageLatitude - previousWaypoint.StorageLatitude <= lanLngBigDeltaUpperThreshold amp;amp;
StorageLongitude - previousWaypoint.StorageLongitude >= lanLngBigDeltaLowerThreshold amp;amp; StorageLongitude - previousWaypoint.StorageLongitude <= lanLngBigDeltaUpperThreshold)
{
positionStorageMode = PositionStorageMode.BigDelta;
}
}
var headerByte = 0;
if (Type == IofXml30WaypointType.Interruption) headerByte |= (1 << 7);
if (timeStorageMode == TimeStorageMode.Milliseconds) headerByte |= (1 << 6);
if (timeStorageMode == TimeStorageMode.Seconds) headerByte |= (1 << 5);
if (positionStorageMode == PositionStorageMode.BigDelta) headerByte |= (1 << 4);
if (positionStorageMode == PositionStorageMode.SmallDelta) headerByte |= (1 << 3);
if (StorageAltitude != null) headerByte |= (1 << 2);
// header byte
stream.WriteByte((byte)headerByte);
// time byte(s)
switch (timeStorageMode)
{
case TimeStorageMode.Full: // 6 bytes
stream.Write(BitConverter.GetBytes(StorageTime).Reverse().ToArray(), 2, 6);
break;
case TimeStorageMode.Milliseconds: // 2 bytes
stream.Write(BitConverter.GetBytes((ushort)(StorageTime - previousWaypoint.StorageTime)).Reverse().ToArray(), 0, 2);
break;
case TimeStorageMode.Seconds: // 1 byte
stream.WriteByte((byte)((StorageTime - previousWaypoint.StorageTime) / 1000));
break;
}
// position bytes
switch (positionStorageMode)
{
case PositionStorageMode.Full: // 4 4 3 bytes
stream.Write(BitConverter.GetBytes(StorageLatitude).Reverse().ToArray(), 0, 4);
stream.Write(BitConverter.GetBytes(StorageLongitude).Reverse().ToArray(), 0, 4);
if (StorageAltitude != null) stream.Write(BitConverter.GetBytes(StorageAltitude.Value).Reverse().ToArray(), 1, 3);
break;
case PositionStorageMode.BigDelta: // 2 2 1 bytes
stream.Write(BitConverter.GetBytes((short)(StorageLatitude - previousWaypoint.StorageLatitude)).Reverse().ToArray(), 0, 2);
stream.Write(BitConverter.GetBytes((short)(StorageLongitude - previousWaypoint.StorageLongitude)).Reverse().ToArray(), 0, 2);
if (StorageAltitude != null) stream.Write(BitConverter.GetBytes((sbyte)(StorageAltitude - previousWaypoint.StorageAltitude).Value), 0, 1);
break;
case PositionStorageMode.SmallDelta: // 1 1 1 bytes
stream.Write(BitConverter.GetBytes((sbyte)(StorageLatitude - previousWaypoint.StorageLatitude)), 0, 1);
stream.Write(BitConverter.GetBytes((sbyte)(StorageLongitude - previousWaypoint.StorageLongitude)), 0, 1);
if (StorageAltitude != null) stream.Write(BitConverter.GetBytes((sbyte)(StorageAltitude - previousWaypoint.StorageAltitude).Value), 0, 1);
break;
}
}
/// <summary>
/// Reads a waypoint in IOF XML 3.0 binary format from a stream.
/// </summary>
/// <param name="stream">The stream to read from.</param>
/// <param name="previousWaypoint">The previous waypoint of the route, or null if this is the first waypoint.</param>
/// <returns></returns>
public static IofXml30Waypoint FromStream(Stream stream, IofXml30Waypoint previousWaypoint)
{
var waypoint = new IofXml30Waypoint();
// header byte
var headerByte = stream.ReadByte();
waypoint.Type = (headerByte amp; (1 << 7)) == 0 ? IofXml30WaypointType.Normal : IofXml30WaypointType.Interruption;
var timeStorageMode = TimeStorageMode.Full;
if ((headerByte amp; (1 << 6)) > 0)
{
timeStorageMode = TimeStorageMode.Milliseconds;
}
else if ((headerByte amp; (1 << 5)) > 0)
{
timeStorageMode = TimeStorageMode.Seconds;
}
var positionStorageMode = PositionStorageMode.Full;
if ((headerByte amp; (1 << 4)) > 0)
{
positionStorageMode = PositionStorageMode.BigDelta;
}
else if ((headerByte amp; (1 << 3)) > 0)
{
positionStorageMode = PositionStorageMode.SmallDelta;
}
var altitudePresent = (headerByte amp; (1 << 2)) > 0;
byte[] bytes;
int b;
// time byte(s)
switch (timeStorageMode)
{
case TimeStorageMode.Full: // 4 bytes
bytes = new byte[8];
stream.Read(bytes, 2, 6);
waypoint.StorageTime = BitConverter.ToUInt64(bytes.Reverse().ToArray(), 0);
break;
case TimeStorageMode.Milliseconds: // 2 bytes
bytes = new byte[2];
stream.Read(bytes, 0, 2);
waypoint.StorageTime = previousWaypoint.StorageTime BitConverter.ToUInt16(bytes.Reverse().ToArray(), 0);
break;
case TimeStorageMode.Seconds: // 1 byte
b = stream.ReadByte();
waypoint.StorageTime = previousWaypoint.StorageTime (ulong)b * 1000;
break;
}
// position bytes
switch (positionStorageMode)
{
case PositionStorageMode.Full: // 4 4 3 bytes
bytes = new byte[4];
stream.Read(bytes, 0, 4);
waypoint.StorageLatitude = BitConverter.ToInt32(bytes.Reverse().ToArray(), 0);
bytes = new byte[4];
stream.Read(bytes, 0, 4);
waypoint.StorageLongitude = BitConverter.ToInt32(bytes.Reverse().ToArray(), 0);
if (altitudePresent)
{
bytes = new byte[4];
stream.Read(bytes, 1, 3);
waypoint.StorageAltitude = BitConverter.ToInt32(bytes.Reverse().ToArray(), 0);
}
break;
case PositionStorageMode.BigDelta: // 2 2 1 bytes
bytes = new byte[2];
stream.Read(bytes, 0, 2);
waypoint.StorageLatitude = previousWaypoint.StorageLatitude BitConverter.ToInt16(bytes.Reverse().ToArray(), 0);
bytes = new byte[2];
stream.Read(bytes, 0, 2);
waypoint.StorageLongitude = previousWaypoint.StorageLongitude BitConverter.ToInt16(bytes.Reverse().ToArray(), 0);
if (altitudePresent)
{
b = stream.ReadByte();
waypoint.StorageAltitude = previousWaypoint.StorageAltitude (sbyte)b;
}
break;
case PositionStorageMode.SmallDelta: // 1 1 1 bytes
b = stream.ReadByte();
waypoint.StorageLatitude = previousWaypoint.StorageLatitude (sbyte)b;
b = stream.ReadByte();
waypoint.StorageLongitude = previousWaypoint.StorageLongitude (sbyte)b;
if (altitudePresent)
{
b = stream.ReadByte();
waypoint.StorageAltitude = previousWaypoint.StorageAltitude (sbyte)b;
}
break;
}
return waypoint;
}
/// <summary>
/// The storage mode for the time of a waypoint.
/// </summary>
private enum TimeStorageMode
{
/// <summary>
/// The time is stored as a 6-byte unsigned integer, and shows the number of milliseconds since January 1, 1900, 00:00:00 UTC.
/// </summary>
Full,
/// <summary>
/// The time is stored as a 2-byte unsigned integer, and shows the number of seconds since the previous waypoint's time.
/// </summary>
Seconds,
/// <summary>
/// The time is stored as a 4-byte unsigned integer, and shows the number of milliseconds since the previous waypoint's time.
/// </summary>
Milliseconds
}
/// <summary>
/// The storage mode for the position (latitude, longitude, altitude) of a waypoint.
/// </summary>
private enum PositionStorageMode
{
/// <summary>
/// The longitude and latitude are stored as microdegrees in 4-byte signed integers, and the altitude is stored as decimeters in a 3-byte signed integer.
/// </summary>
Full,
/// <summary>
/// The longitude and latitude are stored as microdegrees relative to the previous waypoint in 2-byte signed integers, and the altitude is stored as decimeters relative to the previous waypoint in a 3-byte signed integer>.
/// </summary>
BigDelta,
/// <summary>
/// The longitude and latitude are stored as microdegrees relative to the previous waypoint in 1-byte signed integers, and the altitude is stored as decimeters relative to the previous waypoint in a 1-byte signed integer.
/// </summary>
SmallDelta
}
}
/// <summary>
/// The type of waypoint.
/// </summary>
public enum IofXml30WaypointType
{
/// <summary>
/// A normal waypoint.
/// </summary>
Normal,
/// <summary>
/// A waypoint that is the last waypoint before an interruption in the route occurs.
/// </summary>
Interruption
}
Скрипт декодирования PHP
PHP
Сценарий очень похож. Я не могу прикрепить из-за ограничения размера этого сообщения, однако я могу предоставить его, если это необходимо.
Комментарии:
1. маловероятно, что кто-нибудь здесь потратит время на «транслитерирование» кода и предоставит вам рабочее решение. Вы пробовали, где вы застряли? как поток данных попадает в ваше приложение? откуда берется поток (может быть фрагмент, доступный в Inet lalaland)?
2. Я знаю. Да, я пытался, но я застрял
Stream
.NSStream
(который я никогда раньше не использовал), похоже, не имеет такого поведения, какC# Memory Stream
. Я просмотрелNSInputStream
иNSOutputStream
, но я не думаю, что они тоже подходят. Если бы вы могли дать мне представление о том, какойObjective C
объект я должен использовать в качестве потока, я был бы очень признателен. Поток, в котором я считаю, созданIofXml30Route FromByteArray
?. МоиPHP
иC#
знания очень минимальны, извините.