My app allows the user to create a point feature and attach multiple photos to it. The photos are displayed in a custom callout which appears when the user taps the feature. The point is created and the attachments are added to it successfully; I know because I can see the photos when I select the point on the map and no client-side errors are thrown. However, the attachments are gone the next time I open the app. The point appears and I can see it in ArcGIS Pro on the back end, but there are no attachments in the associated table.
This error is logged in the Server Manager: "Unable to complete upload operation, File size or type not supported for this service". The photos are less than 2 MB each and I have never uploaded more than 3 at a time.
I know attachments are enabled for the layer because I successfully added this feature with a photo via ArcGIS Pro and it saved to the database. This leads me to believe the failure is either on the front end or perhaps a setting the attachment is violating, but I don't know how to check that.
Here are the steps to create the feature and any photo attachments:
1. The user presses a button which transitions to a new screen where they select photos.
2. The user selects any number of photos from the gallery or takes new ones with the camera. This is done using UIImagePickerController.
3. The user presses "done". The app prepares to transition to a view controller where the point attributes are set. The point is created in the "prepare" function.
override func <SPAN class="token function">prepare</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">for</SPAN> segue<SPAN class="operator token">:</SPAN> UIStoryboardSegue<SPAN class="punctuation token">,</SPAN> sender<SPAN class="operator token">:</SPAN> Any<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">if</SPAN> segue<SPAN class="punctuation token">.</SPAN>identifier <SPAN class="operator token">==</SPAN> <SPAN class="string token">"create-photo-point-segue"</SPAN> <SPAN class="punctuation token">{</SPAN>
let nc <SPAN class="operator token">=</SPAN> segue<SPAN class="punctuation token">.</SPAN>destination as<SPAN class="operator token">!</SPAN> NewFeatureNavigationController
let vc <SPAN class="operator token">=</SPAN> nc<SPAN class="punctuation token">.</SPAN>topViewController as<SPAN class="operator token">!</SPAN> CreateFeatureViewController
let <SPAN class="keyword token">template</SPAN><SPAN class="operator token">:</SPAN> AGSFeatureTemplate<SPAN class="operator token">?</SPAN> <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>photoFeatureLayer<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN>featureTable as<SPAN class="operator token">?</SPAN> AGSServiceFeatureTable<SPAN class="punctuation token">)</SPAN><SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN>featureTemplates<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN>
vc<SPAN class="punctuation token">.</SPAN><SPAN class="keyword token">template</SPAN> <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">template</SPAN>
<SPAN class="comment token">//Create the new photo point feature with the photo attachments</SPAN>
let newAgsFeature <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>photoFeatureLayer<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN>featureTable as<SPAN class="operator token">?</SPAN> AGSServiceFeatureTable<SPAN class="punctuation token">)</SPAN><SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">createFeature</SPAN><SPAN class="punctuation token">(</SPAN>with<SPAN class="operator token">:</SPAN> <SPAN class="keyword token">template</SPAN><SPAN class="operator token">!</SPAN><SPAN class="punctuation token">)</SPAN>
newAgsFeature<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">.</SPAN>attributes<SPAN class="punctuation token">.</SPAN><SPAN class="token function">setValue</SPAN><SPAN class="punctuation token">(</SPAN>primaryLocation<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN>latitude<SPAN class="punctuation token">,</SPAN> forKey<SPAN class="operator token">:</SPAN> <SPAN class="string token">"LATITUDE"</SPAN><SPAN class="punctuation token">)</SPAN>
newAgsFeature<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">.</SPAN>attributes<SPAN class="punctuation token">.</SPAN><SPAN class="token function">setValue</SPAN><SPAN class="punctuation token">(</SPAN>primaryLocation<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN>longitude<SPAN class="punctuation token">,</SPAN> forKey<SPAN class="operator token">:</SPAN> <SPAN class="string token">"LONGITUDE"</SPAN><SPAN class="punctuation token">)</SPAN>
newAgsFeature<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">.</SPAN>attributes<SPAN class="punctuation token">.</SPAN><SPAN class="token function">setValue</SPAN><SPAN class="punctuation token">(</SPAN>primaryDate<SPAN class="punctuation token">,</SPAN> forKey<SPAN class="operator token">:</SPAN> <SPAN class="string token">"TIMESTAMP"</SPAN><SPAN class="punctuation token">)</SPAN>
let point <SPAN class="operator token">=</SPAN> <SPAN class="token function">AGSPoint</SPAN><SPAN class="punctuation token">(</SPAN>x<SPAN class="operator token">:</SPAN> primaryLocation<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">.</SPAN>longitude <SPAN class="punctuation token">,</SPAN> y<SPAN class="operator token">:</SPAN> primaryLocation<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">.</SPAN>latitude<SPAN class="punctuation token">,</SPAN> spatialReference<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="token function">wgs84</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
newAgsFeature<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">.</SPAN>geometry <SPAN class="operator token">=</SPAN> point
<SPAN class="token function">attachTxtDocs</SPAN><SPAN class="punctuation token">(</SPAN>feature<SPAN class="operator token">:</SPAN> newAgsFeature<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">,</SPAN> photoArray<SPAN class="operator token">:</SPAN> photoSelectionData<SPAN class="punctuation token">)</SPAN>
vc<SPAN class="punctuation token">.</SPAN>feature <SPAN class="operator token">=</SPAN> newAgsFeature
vc<SPAN class="punctuation token">.</SPAN>featureAttachments <SPAN class="operator token">=</SPAN> photoSelectionData
vc<SPAN class="punctuation token">.</SPAN>hasAttachments <SPAN class="operator token">=</SPAN> <SPAN class="token boolean">true</SPAN>
vc<SPAN class="punctuation token">.</SPAN>layer <SPAN class="operator token">=</SPAN> photoFeatureLayer<SPAN class="operator token">!</SPAN>
nc<SPAN class="punctuation token">.</SPAN>collectionPoint <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>self<SPAN class="punctuation token">.</SPAN>navigationController as<SPAN class="operator token">!</SPAN> AddPhotoFeatureNavigationController<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>collectionPoint
let mapVC <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>self<SPAN class="punctuation token">.</SPAN>navigationController as<SPAN class="operator token">!</SPAN> AddPhotoFeatureNavigationController<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>mapVC
mapVC<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN>navController <SPAN class="operator token">=</SPAN> nc
nc<SPAN class="punctuation token">.</SPAN>mapVC <SPAN class="operator token">=</SPAN> mapVC
nc<SPAN class="punctuation token">.</SPAN>intermediateVC <SPAN class="operator token">=</SPAN> self
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>3a. The photos are serialized to txt documents (necessary to capture metadata) and attached to the newly-created point. I'm aware that because the attachment is a text document that could be why it doesn't save, but I doubt it because I have an alternate function which does not serialize the photo and it experiences the same problem.
func <SPAN class="token function">attachTxtDocs</SPAN><SPAN class="punctuation token">(</SPAN>feature<SPAN class="operator token">:</SPAN>AGSArcGISFeature<SPAN class="punctuation token">,</SPAN> photoArray<SPAN class="operator token">:</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">[</SPAN>UIImagePickerController<SPAN class="punctuation token">.</SPAN>InfoKey<SPAN class="operator token">:</SPAN>Any<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN>
var i <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN>
var tempFileUrls<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">[</SPAN>URL<SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN>
DispatchQueue<SPAN class="punctuation token">.</SPAN>main<SPAN class="punctuation token">.</SPAN>async <SPAN class="punctuation token">{</SPAN>
SVProgressHUD<SPAN class="punctuation token">.</SPAN><SPAN class="token function">show</SPAN><SPAN class="punctuation token">(</SPAN>withStatus<SPAN class="operator token">:</SPAN> <SPAN class="string token">"Attaching Photos..."</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">for</SPAN> photo in photoArray <SPAN class="punctuation token">{</SPAN>
var type<SPAN class="operator token">:</SPAN> String
<SPAN class="keyword token">if</SPAN> let typeOptional <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>photo<SPAN class="punctuation token">[</SPAN>UIImagePickerController<SPAN class="punctuation token">.</SPAN>InfoKey<SPAN class="punctuation token">.</SPAN>imageURL<SPAN class="punctuation token">]</SPAN> as<SPAN class="operator token">!</SPAN> URL<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN>
let urlTokens <SPAN class="operator token">=</SPAN> typeOptional<SPAN class="punctuation token">.</SPAN>absoluteString<SPAN class="punctuation token">.</SPAN><SPAN class="token function">split</SPAN><SPAN class="punctuation token">(</SPAN>separator<SPAN class="operator token">:</SPAN> <SPAN class="string token">"."</SPAN><SPAN class="punctuation token">)</SPAN>
type <SPAN class="operator token">=</SPAN> urlTokens<SPAN class="punctuation token">[</SPAN>urlTokens<SPAN class="punctuation token">.</SPAN>count <SPAN class="operator token">-</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>description
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN>
type <SPAN class="operator token">=</SPAN> <SPAN class="string token">"jpg"</SPAN>
<SPAN class="punctuation token">}</SPAN>
var imageData<SPAN class="operator token">:</SPAN> Data<SPAN class="operator token">?</SPAN>
<SPAN class="keyword token">switch</SPAN> type <SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">case</SPAN> <SPAN class="string token">"jpg"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"jpeg"</SPAN><SPAN class="operator token">:</SPAN>
imageData <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>photo<SPAN class="punctuation token">[</SPAN>UIImagePickerController<SPAN class="punctuation token">.</SPAN>InfoKey<SPAN class="punctuation token">.</SPAN>originalImage<SPAN class="punctuation token">]</SPAN> as<SPAN class="operator token">!</SPAN> UIImage<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">jpegData</SPAN><SPAN class="punctuation token">(</SPAN>compressionQuality<SPAN class="operator token">:</SPAN> <SPAN class="number token">0.5</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="operator token">!</SPAN>
<SPAN class="keyword token">case</SPAN> <SPAN class="string token">"png"</SPAN><SPAN class="operator token">:</SPAN>
imageData <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>photo<SPAN class="punctuation token">[</SPAN>UIImagePickerController<SPAN class="punctuation token">.</SPAN>InfoKey<SPAN class="punctuation token">.</SPAN>originalImage<SPAN class="punctuation token">]</SPAN> as<SPAN class="operator token">!</SPAN> UIImage<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">pngData</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="operator token">!</SPAN>
<SPAN class="keyword token">default</SPAN><SPAN class="operator token">:</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"Invalid type"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
guard imageData <SPAN class="operator token">!=</SPAN> nil <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN>
SVProgressHUD<SPAN class="punctuation token">.</SPAN><SPAN class="token function">dismiss</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN>
<SPAN class="punctuation token">}</SPAN>
let fileName <SPAN class="operator token">=</SPAN> <SPAN class="token function">serializePhoto</SPAN><SPAN class="punctuation token">(</SPAN>lat<SPAN class="operator token">:</SPAN> <SPAN class="token function">String</SPAN><SPAN class="punctuation token">(</SPAN>geolocations<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>latitude<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
lon<SPAN class="operator token">:</SPAN> <SPAN class="token function">String</SPAN><SPAN class="punctuation token">(</SPAN>geolocations<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>longitude<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
timestamp<SPAN class="operator token">:</SPAN> timestamps<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>description<SPAN class="punctuation token">,</SPAN>
fileType<SPAN class="operator token">:</SPAN> type<SPAN class="punctuation token">,</SPAN>
photoData<SPAN class="operator token">:</SPAN> imageData<SPAN class="operator token">!</SPAN><SPAN class="punctuation token">)</SPAN>
let fileUrl <SPAN class="operator token">=</SPAN> <SPAN class="token function">URL</SPAN><SPAN class="punctuation token">(</SPAN>fileURLWithPath<SPAN class="operator token">:</SPAN> <SPAN class="token function">NSTemporaryDirectory</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">appendingPathComponent</SPAN><SPAN class="punctuation token">(</SPAN>fileName<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">appendingPathExtension</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"txt"</SPAN><SPAN class="punctuation token">)</SPAN>
tempFileUrls<SPAN class="punctuation token">.</SPAN><SPAN class="token function">append</SPAN><SPAN class="punctuation token">(</SPAN>fileUrl<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">do</SPAN> <SPAN class="punctuation token">{</SPAN>
let photoData <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">try</SPAN> <SPAN class="token function">Data</SPAN><SPAN class="punctuation token">(</SPAN>contentsOf<SPAN class="operator token">:</SPAN> fileUrl<SPAN class="punctuation token">)</SPAN>
feature<SPAN class="punctuation token">.</SPAN><SPAN class="token function">addAttachment</SPAN><SPAN class="punctuation token">(</SPAN>withName<SPAN class="operator token">:</SPAN> <SPAN class="string token">"attachment"</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="token function">String</SPAN><SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
contentType<SPAN class="operator token">:</SPAN> <SPAN class="string token">"txt"</SPAN><SPAN class="punctuation token">,</SPAN>
data<SPAN class="operator token">:</SPAN> photoData<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="punctuation token">(</SPAN>attachment<SPAN class="punctuation token">,</SPAN> error<SPAN class="punctuation token">)</SPAN> in
SVProgressHUD<SPAN class="punctuation token">.</SPAN><SPAN class="token function">dismiss</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> let error <SPAN class="operator token">=</SPAN> error <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN>error<SPAN class="punctuation token">.</SPAN>localizedDescription<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">if</SPAN> attachment <SPAN class="operator token">!=</SPAN> nil <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"Photo successfully attached."</SPAN><SPAN class="punctuation token">)</SPAN>
self<SPAN class="punctuation token">.</SPAN><SPAN class="token function">removeTempDoc</SPAN><SPAN class="punctuation token">(</SPAN>fileUrl<SPAN class="operator token">:</SPAN> fileUrl<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">catch</SPAN> <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"Failed to fetch photo data from "</SPAN> <SPAN class="operator token">+</SPAN> fileUrl<SPAN class="punctuation token">.</SPAN>absoluteString<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN>
<SPAN class="punctuation token">}</SPAN>
i <SPAN class="operator token">+</SPAN><SPAN class="operator token">=</SPAN> <SPAN class="number token">1</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>4. The feature's attributes are set and is loaded after the transition to the final view.
5. The user confirms the attributes are correct and hits "save". The edits are applied to the table.
func <SPAN class="token function">applyEdits</SPAN><SPAN class="punctuation token">(</SPAN>to table<SPAN class="operator token">:</SPAN>AGSServiceFeatureTable<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN>
SVProgressHUD<SPAN class="punctuation token">.</SPAN><SPAN class="token function">setDefaultMaskType</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">.</SPAN>black<SPAN class="punctuation token">)</SPAN>
DispatchQueue<SPAN class="punctuation token">.</SPAN>main<SPAN class="punctuation token">.</SPAN>async <SPAN class="punctuation token">{</SPAN>
SVProgressHUD<SPAN class="punctuation token">.</SPAN><SPAN class="token function">show</SPAN><SPAN class="punctuation token">(</SPAN>withStatus<SPAN class="operator token">:</SPAN> <SPAN class="string token">"Saving"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
table<SPAN class="punctuation token">.</SPAN><SPAN class="token function">applyEdits</SPAN><SPAN class="punctuation token">(</SPAN>completion<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">,</SPAN> error<SPAN class="punctuation token">)</SPAN> in
SVProgressHUD<SPAN class="punctuation token">.</SPAN><SPAN class="token function">dismiss</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> let error <SPAN class="operator token">=</SPAN> error <SPAN class="punctuation token">{</SPAN>
<SPAN class="token function">print</SPAN><SPAN class="punctuation token">(</SPAN>error<SPAN class="punctuation token">)</SPAN>
let alert <SPAN class="operator token">=</SPAN> <SPAN class="token function">UIAlertController</SPAN><SPAN class="punctuation token">(</SPAN>title<SPAN class="operator token">:</SPAN> <SPAN class="string token">"Alert!"</SPAN><SPAN class="punctuation token">,</SPAN> message<SPAN class="operator token">:</SPAN> <SPAN class="string token">"Unable to create feature: \(error.localizedDescription)"</SPAN><SPAN class="punctuation token">,</SPAN> preferredStyle<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">.</SPAN>alert<SPAN class="punctuation token">)</SPAN>
let okAction <SPAN class="operator token">=</SPAN> <SPAN class="token function">UIAlertAction</SPAN><SPAN class="punctuation token">(</SPAN>title<SPAN class="operator token">:</SPAN> <SPAN class="string token">"OK"</SPAN><SPAN class="punctuation token">,</SPAN> style<SPAN class="operator token">:</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="keyword token">default</SPAN><SPAN class="punctuation token">,</SPAN> handler<SPAN class="operator token">:</SPAN> nil<SPAN class="punctuation token">)</SPAN>
alert<SPAN class="punctuation token">.</SPAN><SPAN class="token function">addAction</SPAN><SPAN class="punctuation token">(</SPAN>okAction<SPAN class="punctuation token">)</SPAN>
self<SPAN class="punctuation token">.</SPAN><SPAN class="token function">present</SPAN><SPAN class="punctuation token">(</SPAN>alert<SPAN class="punctuation token">,</SPAN> animated<SPAN class="operator token">:</SPAN> <SPAN class="token boolean">true</SPAN><SPAN class="punctuation token">,</SPAN> completion<SPAN class="operator token">:</SPAN> nil<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">if</SPAN> self<SPAN class="punctuation token">.</SPAN>referenceFeature <SPAN class="operator token">!=</SPAN> nil <SPAN class="punctuation token">{</SPAN>
self<SPAN class="punctuation token">.</SPAN><SPAN class="token function">deleteReferenceFeature</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN>
self<SPAN class="punctuation token">.</SPAN>navigationController<SPAN class="operator token">?</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">dismiss</SPAN><SPAN class="punctuation token">(</SPAN>animated<SPAN class="operator token">:</SPAN> <SPAN class="token boolean">true</SPAN><SPAN class="punctuation token">,</SPAN> completion<SPAN class="operator token">:</SPAN> nil<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>This app uses ArcGIS Runtime v100.6. The back end is ArcServer 10.7.1.
Can someone offer a solution?