|
POST
|
When an iOS application goes into background there are two conditions that can occur in regards to receiving location The user just goes to home screen or goes to another application that is not connected to the external gps device The user goes to an application that does connect to the external gps device. This is a common occurrence if the user need to go into an application that connects to an NTrip server. What I have observed is that in each of these condition is it seems different things happen to the underlying EASession associated to the EAAccessoryStream object public EAAccessoryStream(EAAccessory accessory, string protocol)
{
this._accessory = accessory;
this._session = new EASession(accessory, protocol);
this._session.InputStream?.Open();
this._session.OutputStream?.Open();
} In case (1), the session is maintained in case (2) the EASession object would seem to be disposed. The problem is that there is no way to know which case has occurred. They way I have implemented things is that when the user returns to the application //_sxblueAccessory is connected EAAccessory Protocal is the protocal string
_internaLocationDataSource = NmeaLocationDataSource.FromAccessory(_sxblueAccessory, Protocal);
_internaLocationDataSource.StartAsync(); In case (2) above this works without issue. However, in case (1) you will get a "Starting" status changed followed by a "Failed to Start" status message. In this case there is also an ErrorOccured notification sent with the following: Could not initialize an instance of the type 'ExternalAccessory.EASession': the native 'initWithAccessory:forProtocol:' method returned nil. It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false. What appears to happen in this case is that when it tries to create the EAAccessoryStream is it throws this exception because there is already an existing EASession object being held by the NmeaLocationDataSource object. This is somewhat conjecture just based on what I observe through a lot of logging and going through various scenarios in testing. As there is no access to the underlying EASession it is hard to see in exactly what happening. So what would a best practice of how to manage the NmeaLocationDataSource when the app goes into background. What I am trying now is to call StopAsync when the app goes into background. This allows just restarting everything without error when the app comes back into foreground. This does seem to be working. Honestly, I am not too happy with this solution. I think the location provider should be able to run in the background unless it is forced to stop because another app took over the connection to the external device. However, I am unable to see anything that indicates which of the two scenarios has occurred to allow the application to restore in the correct way based on the different conditions.
... View more
02-02-2023
09:46 AM
|
0
|
0
|
768
|
|
POST
|
@ReneParise We are aware of the SxToolbox app and that is the current approach being used. We would prefer to not require the users have a second application running in the background and require them to return to this application to confirm they are connected to the NTrip server. The client is using the SX Blue Platinum (they have over 100 devices). The workflow of needing a second application has been arduous to the end users and we are looking for a way to have greater control within the application, giving an ability to keep the users better informed as to status of the NTrip data. We do seem to be able to write out to the stream of the device, however, it does not seem to be returning a NMEA sentence indicating a RTK float/fix fix type. This confusing, as it seems based on samples (including one provided by your company a few years back) we are writing the data correctly. It is very unclear how the SxToolbox application would be writing to the device differently than how we are doing it directly from the our application. Based on various technical documents, it seems to indicate that if an NTrip stream was being sent on the port the Platinum would recognize that it is a correction data stream. We would love to talk with someone at Geneq that could help in this matter, you can direct message me if you could help in this regard Thanks -Joe
... View more
01-10-2023
08:46 AM
|
0
|
1
|
2156
|
|
POST
|
@dotMorten_esri I have been looking at some things, which I am not able to check directly in the API but did with the previous version of the External Accessory listener I used. What I found is that when setup the way EAAccessoryStream is setup if you check: _session.OutputStream.HasSpaceAvailable(); it return false and if you try and do a Write operation on the stream the errors I see the same error described above. However, if I add _session.OutputStream.Schedule(NSRunLoop.Current, NSRunLoopMode.Default); Prior to calling _session.OutputStream.Open(); Then I am getting a true for HasSpaceAvailable(); and not seeing an error in the debug console. I need to make some changes in my app though to truly test the correction with my old listener because of changes I made to use the API now it does not process that output completely. In doing the testing I copied the EAAccessoryStream but with a couple changes to see what was happening public override void Write(byte[] buffer, int offset, int count)
{
if ( _session?.OutputStream == null ) return;
bool spaceAvailable = _session.OutputStream.HasSpaceAvailable();
Console.WriteLine($"Calling stream Write - HasSpaceAvailable = {spaceAvailable}");
_session.OutputStream.Write(buffer, offset, (uint)count);
}
public override bool CanWrite => _session.OutputStream != null && _session.OutputStream.HasSpaceAvailable(); At first I had implemented a dummy class inheriting from NSStreamDelegate and assigns as delegate, but during testing that did not seem needed, although can give some additional information Thanks -Joe
... View more
12-14-2022
12:32 PM
|
0
|
0
|
2203
|
|
POST
|
We have a Geneq SXBlue Platinum. They have an app called SX Blue Toolbox, which when connected and running is providing a RTK Float or better fix and that is seen in the application. Most of the iOS stuff I have seen is in Objective-C (I think I saw a swift one). So is hard to compare things directly. I see the output stream is opened in the API, and seems a pretty straight forward operation to be calling Write Thanks
... View more
12-13-2022
03:36 PM
|
0
|
4
|
2244
|
|
POST
|
We are trying to implement an NTrip client directly into our field application so that we have more available information and do not need the users to have a second app running in background that process the data. I've looked at a lot of sample code including the demo app ExternalNmeaGPS.Desktop It all seems pretty straight forward (in a complex sort of way), but basically get the stream from the NTrip source and write it onto the device stream I am using Runtime 100.16 in an iOS application. Using the NmeaLocationDataSource. When using the external application we see RTK Float fix type and I would expect to see the same in our application. I can see that we are receiving the NTrip source stream, but there seems to be an issue in the writing. I get the following error in the output window when running in the debugger Mobile.AsBuilt.iOS[30962:12345748] ERROR - /Library/Caches/com.apple.xbs/Sources/ExternalAccessory/EAOutputStream.m:-[EAOutputStream write:maxLength:] - 332 failed to write because stream does not have space available I have searched around on this error and cannot find anything outside of one place that mentions writing to the stream on the main thread (related to a different issue) which did not change anything. The issue looks to be occurring pretty deep into the Xamarin iOS API and not sure what could be changed on my side (or even within the EAAccessoryStream). Unfortunately, I have some technical issues connecting the GPS device to Windows and so am not able to really test out the windows solution provided by the ExternalNmeaGPS demo app. Thoughts? @dotMorten_esri
... View more
12-13-2022
03:11 PM
|
0
|
10
|
2640
|
|
POST
|
Look at Enum QueryFeatureFields this should allow you to set to return IdsOnly
... View more
12-12-2022
08:31 AM
|
0
|
3
|
1759
|
|
POST
|
Sorry slow replying Yes this is for replicas that have been deployed since the original deployment, so a couple years+ and have just been growing over time I was looking at the sqllite vaccum command and just need to find some better info on exactly how to run on the db, but not as part of a update or insert statement The easiest thing would be if we could setup something that could run on a periodic basis, maybe at app startup. Pushing an updated application is the simplest process in place
... View more
12-12-2022
08:13 AM
|
0
|
0
|
1050
|
|
POST
|
Hi, There may be a better place to post this, but not sure where We have an app that has been in the field for a while (few years). What we are seeing is unexplained growth in the replicas which does not match the amount of data being added. There are replicas growing to almost a GB in size, but if we regenerated the replica (so has the same number of records) it is about 1/3 that size. Would love to understand why this occurs, and looking from a solution that could compress these down so we do not have to push new replicas (this is deployed to close to 1000 devices) Thanks - joe
... View more
12-07-2022
06:36 AM
|
0
|
3
|
1126
|
|
POST
|
Just use HttpClient to make a call to the endpoint and see if you get a response or a timeout before trying to load the map. This uses the generic sharing Url, but could use the Url of the basemap itself public override async Task<bool> CheckIsConnectedAsync()
{
try
{
var tokenUri = new Uri($"{ConnectionUrl}/sharing/rest?f=json");
HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(7) };
var result = await client.GetStringAsync(tokenUri);
var jsonObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
return jsonObject.ContainsKey("currentVersion");
}
catch ( TaskCanceledException )
{
//timeout - server down
return false;
}
catch ( Exception )
{
//Can connect but server not fully up and running
return false;
}
} If you are using Xamarin the Essentials library has methods to check general device connectivity as a way to look at that.
... View more
12-05-2022
08:31 AM
|
1
|
0
|
2046
|
|
POST
|
I know this is old, but if anyone comes here looking for the solution I have posted it another thread. Create PortalItem with zip file
... View more
10-20-2022
12:14 PM
|
0
|
0
|
2078
|
|
POST
|
Never found a way to get anything to work with the Runtime API, but was able to do using the rest endpoint directly. string zipfileName = CreateProjectZipfile(projectItem);
/* Does not seem that Runtime API handles creating a zip file item, so using rest API directly
/* https://developers.arcgis.com/rest/users-groups-and-items/add-item.htm */
string url = $"https://www.arcgis.com/sharing/rest/content/users/{portal.User?.UserName}/additem";
using ( var formContent = new MultipartFormDataContent() )
{
AddStringContent(formContent, projectItem);
AddFileContent(formContent, zipfileName, projectItem);
using ( HttpClient client = new HttpClient(new ArcGISHttpClientHandler()) )
{
var response = await client.PostAsync(url, formContent);
var json = await response.Content.ReadAsStringAsync();
await ShareItemWithGroupAsync(json);
}
}
private void AddStringContent(MultipartFormDataContent formContent, ProjectItem projectItem)
{
Dictionary<string, string> parameters = new Dictionary<string, string>()
{
{ "multipart", "false" },
{ "title", projectItem.Title },
{ "type", "Code Sample" },
{ "async", "false" },
{ "f", "json" }
};
// For MultipartFormDataContent paramaters needs to be added as individual StringContent objects. FormUrlEncodedContent does not work.
foreach (var keyValuePair in parameters)
{
formContent.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
}
}
private void AddFileContent(MultipartFormDataContent formContent, string outputfile, ProjectItem projectItem)
{
var byteArrayContent = new ByteArrayContent(File.ReadAllBytes(outputfile));
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-zip-compressed");
byteArrayContent.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse("form-data");
byteArrayContent.Headers.ContentDisposition.FileName = $"{projectItem.Title}.zip";
// ContentDisposition.Name needs to match the parameter name
byteArrayContent.Headers.ContentDisposition.Name = "file";
formContent.Add(byteArrayContent);
}
... View more
10-20-2022
12:11 PM
|
0
|
0
|
1959
|
|
POST
|
No exceptions are being thrown, it just does not return from the method call
... View more
10-19-2022
01:08 PM
|
1
|
0
|
1977
|
|
POST
|
We are trying to upload zip files to AGOL. If I was doing in AGOL I would create the item, define it as a Code Sample (which will allow a generic zip file). Hoped we could do this in Runtime (100.15). I see this old thread How to create a new FeatureService PortalItem which seems to indicate only saving Maps is supported, but it is 3 years old so would hope that is no longer the case. Seems pretty simple: ZipFile.CreateFromDirectory(projectItem.MapPackagePath, outputfile);
var portalItem = new PortalItem(portal, PortalItemType.CodeSample, projectItem.Title);
using ( var fileStream = File.OpenRead(outputfile) )
{
await portalItem.UpdateDataAsync(fileStream);
}
await portal.User.AddPortalItemAsync(portalItem);
await portalItem.ShareWithGroupsAsync(new[] { group }); Couple problems occur. It requires that the user re-enter credentials on the call to new PortalItem even though authenticated The primary issue: it never returns from the await portalItem.UpdateDataAsync. It just hangs and so cannot ever put the item in AGOL Is what I need to do supported? If so what would be a correct way to do this Thanks - Joe
... View more
10-19-2022
08:01 AM
|
0
|
3
|
2008
|
|
POST
|
Hi, We are getting an error trying to publish a map with a dimension layer for use offline (ArcMap). Are these layer types restricted from been taken offline? Thanks - Joe
... View more
10-11-2022
08:04 AM
|
0
|
0
|
584
|
|
POST
|
One thing you are not doing is calling .LoadAsync(). Personally I don't like directly calling a async method from a constructor. The way I do something similar. Create a simple event LoadMapEvent public MainWindowViewModel(IEventAggregator eventAggregator)
{
//Allow async for loading map
eventAggregator.GetEvent<LoadMapEvent>().Subscribe(OnLoadMap);
eventAggregator.GetEvent<LoadMapEvent>().Publish();
}
private async void OnLoadMap()
{
try
{
//add layers
await Map.LoadAsync();
}
catch (Exception e)
{
_log?.Error(e, e.Message);
}
}
... View more
09-29-2022
01:38 PM
|
0
|
1
|
1129
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 05-11-2026 09:07 AM | |
| 1 | 10-23-2025 12:16 PM | |
| 1 | 10-19-2022 01:08 PM | |
| 1 | 09-03-2025 09:25 AM | |
| 1 | 04-16-2025 12:37 PM |
| Online Status |
Offline
|
| Date Last Visited |
Tuesday
|