Xamarin Apple iOs FilePicker - Cant Pick File? - ios

Trying to get my App to work on iOS now - and wow! This is way harder than I thought.
OK, So I have a filepicker that picks a file. pretty simple (code below.) . With iOs. The file picker dialog opens, and I can click the file I want , but nothing happens - until I hit cancel, then the code continues to run... (pickresult != null).. it is null - code stops...
https://photos.app.goo.gl/fGD5SPtCqdMYE8AS7
var customFileType =
new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
{
{ DevicePlatform.iOS, new[] { "com.microsoft.word.doc" } }, // or general UTType values
{ DevicePlatform.Android, new[] { "application/doc" } },
{ DevicePlatform.UWP, new[] { ".doc" } },
{ DevicePlatform.Tizen, new[] { "*/*" } },
{ DevicePlatform.macOS, new[] { "doc" } }, // or general UTType values
});
string OutupPath;
var pickResult = await FilePicker.PickAsync(new PickOptions
{
FileTypes = customFileType,
PickerTitle = "Select Doc File"
}) ;
if (pickResult != null)
{
OutupPath = pickResult.FullPath.ToString();
App.docFilePath = OutupPath;
LoadingText = pickResult.FileName.ToString();
DbFileName = LoadingText;
}
else {
return;
}
Note - I am developing on Win10 vs 2022. And I am new to iOs. I just got my apple dev account up and running. The Android version and Windows version of this work flawlessly.
Not sure where I should be looking to solve this glitch.
https://photos.app.goo.gl/fGD5SPtCqdMYE8AS7
Original code with no options
private async void Button_Clicked(object sender, EventArgs e)
{
var pickResult = await FilePicker.PickAsync();
if (pickResult != null)
{
FileLabel.Text = pickResult.FileName.ToString();
}
else {
await DisplayAlert("Alert", "No File Selected", "OK");
}
}

What about adding org.openxmlformats.wordprocessingml.document in file types as well ?
The actual type for the file may be docx, so just have a try .
Refer to
https://learn.microsoft.com/en-us/answers/questions/362776/xamarin-file-picker-file-types-for-ios.html
https://stackoverflow.com/a/51592769/8187800
Update (specify doc type in PickOptions)
var customFileType =
new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
{
{ DevicePlatform.iOS, new[] { "com.microsoft.word.doc","org.openxmlformats.wordprocessingml.document" } }, // or general UTType values
{ DevicePlatform.Android, new[] { "application/doc" } },
{ DevicePlatform.UWP, new[] { ".doc" } },
{ DevicePlatform.Tizen, new[] { "*/*" } },
{ DevicePlatform.macOS, new[] { "doc" } }, // or general UTType values
});
var pickResult = await FilePicker.PickAsync(new PickOptions
{
FileTypes = customFileType,
PickerTitle = "Select Doc File"
}) ;

Related

Received files from axios in c# mvc

I trying, searching since several hours and no success
I've a mvc/vue/quasar application where I try to upload a photo from a button
In my cshtml file
<q-input type="file" ref="myFileAvatar" v-on:change="handleFileUpload()" v-model="avatar" style="display:none" accept="image/*"/>
<q-btn round color="primary" icon="cloud_upload" #click="getAvatar" ></q-btn >
I send file from my js, method section
getAvatar: function () {this.$refs.myFileAvatar.$el.click()},
handleFileUpload() {
//const files = Array.from(this.avatar).filter((file) => { return file.size < 102500 && file.type.substring(0, 6) == 'image/' });
let formData = new FormData();
formData.append('ownerID', this.profildata.ownerid);
formData.append('file', this.avatar);
axios.post('/forms/default/uploadProfilImage', formData, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(function (response) {
//TODO
});
}
And in my controler
public JsonNetResult uploadProfilImage(Guid ownerID, HttpPostedFileBase file)
{
resultModel resultUpload = new resultModel();
if (this.Request.Files != null && this.Request.Files.Count == 1)//My old version with q-uploader
{
}
else { resultUpload.status = resultMessage.resultValue.error; resultUpload.message = "Oups, ou sont les fichiers"; }
return JsonNetResult.JsonNet(resultUpload);
}
Problem : file is null even if in developper mode in chrome, I see file is a FileList
ownerID is good... I try several type instead of HttpPostedFileBase but nothing (execpt object give a array of string...)
thanks for your help
finally...
It's a type of parameter problem like I thougth
handleFileUpload() {
if (this.avatar[0].size < 102500 && this.avatar[0].type.substring(0, 6) == 'image/') {
let formData = new FormData();
formData.append('file', this.avatar[0]);//One file
formData.append('ownerID', this.profildata.ownerid);
let self = this
axios.post('/forms/default/uploadProfilImage', formData, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(function (response) {
if (response.data.status == 0) { self.profildata.idFichierAvatar = response.data.model.id; } else { self.showNotifError(response.data.message); }
this.avatar = '';
});
}
else { this.showNotifError("L'image ne répond pas aux critères");}
}
and mvc side
[HttpPost]
public JsonNetResult uploadProfilImage(HttpPostedFileBase file,Guid ownerID )
{
resultModel resultUpload = new resultModel();
if (file != null)
{
}
else { resultUpload.status = resultMessage.resultValue.error; resultUpload.message = "Oups, ou sont les fichiers"; }
return JsonNetResult.JsonNet(resultUpload);
}
##UPDATE : Multiple##
And for multiple files
in q-input add multiple property
in server side :
[HttpPost]
public JsonNetResult uploadProfilImage(HttpPostedFileBase[] files,Guid ownerID )
And To send files from js
handleFile() {
let formData = new FormData();
for (var i = 0; i < this.newfiles.length; i++) {
let fichier = this.newfiles[i];
formData.append('files[' + i + ']', fichier);
}
formData.append('ownerID', this.ownerid);
let self = this
axios.post('/files/joinFile/uploadFiles', formData, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(function (response) {
if (response.data.status == 0) { self.files = response.data.model; } else { self.showNotifError(response.data.message); }
this.newfiles = '';
});
}
I hope it's full for everyone who have same problem :-)

Rxjs BehaviorSubject error handling when used with mergemap

I have the following code
#Injectable()
export class ReceptionService {
private generalInfoDataSrc$ = new BehaviorSubject<any>(null);
public generalInfoData = this.generalInfoDataSrc$.asObservable();
setGeneralInfo(dataSrc: GeneralInfoMModal) {
this.generalInfoDataSrc$.next(dataSrc);
}
}
From my component1 I will set the above as
OnSelect(patient: any) {
let generalInfo = new GeneralInfoMModal();
generalInfo.id = patient.id;
// some other code here
// this.recepService.setGeneralInfo(generalInfo);
}
// from component2
//
ngOnInit() { getPatientDetails() }
getPatientDetails() {
this.receptionService.generalInfoData.pipe(mergeMap(response => {
if (response && response.id) {
this.loading = true;
return this.receptionService.get('User/Get' + response.id, this.sourceobj);
} else {
return of(null);
}
}), takeUntil(this.unsubscribe$)).subscribe(response => {
this.patient = response;
this.loading = false;
}, error => {
this.loading = false;
// this.utility.showMsg('An error occurred while getting user.')
}, () => {
})
}
Every things works well. I keep on selecting a user thereby calling the User/Get api. But if in case if the api returns an error then error part is executed after which when there is a change in behaviorsubject(user is selected) it doesn't call the User/Get. Is there other way of handling errors with behaviorsubject or any other approach to handle the idea. How a behaviorsubject should be used in such a case.
If you are using the same behavior subject over and over again, and if there is an error, you need to set the behavior subject back to null, so that when the next user is set, it will get the latest value.
Try something like this:
getPatientDetails() {
this.receptionService.generalInfoData.pipe(mergeMap(response => {
if (response && response.id) {
this.loading = true;
return this.receptionService.get('User/Get' + response.id, this.sourceobj);
} else {
return of(null);
}
}), takeUntil(this.unsubscribe$)).subscribe(response => {
this.patient = response;
this.loading = false;
}, error => {
this.loading = false;
///////////////////////////////// ADD THIS LINE ///////////////////////
this.recepService.setGeneralInfo(null);
// this.utility.showMsg('An error occurred while getting user.')
}, () => {
})

How can I open txt file from Icloud drive using Xamarin.Essentials: File Picker?

Help me please about opening txt files on iPhone.
private async Task ExecuteOpenFileCommandAsync()
{
Device.BeginInvokeOnMainThread(async () =>
{
var customFileType =
new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
{
{ DevicePlatform.iOS, new[] { "blablabla" } },
{ DevicePlatform.Android, new[] { "text/plain" } }
});
var options = new PickOptions
{
PickerTitle = "Please select a file",
FileTypes = customFileType,
};
await PickAndShow(options);
});
}
I dont know, what I need to write instead "blablabla"
Thank you.
I found the answer "public.text" resolved the problem.

Passing String parameter Value Through angular Service parameter Value is Automatically Appends Some Special Character

Here's my Angular controller
//Save And Update
$scope.AddUpdateBusinessType = function() {
var businessType = {
Code: $scope.businessCode,
BusiType: $scope.businessType
};
var getBusinessTypeAction = $scope.BusinessTypeAction;
if (getBusinessTypeAction == "Update") {
businessType.BusinessTypeId = $scope.businessTypeId;
var getBusinessTypeData = businessTypeService.updateBusinessType(businessType);
getBusinessTypeData.then(function (msg) {
GetAllBusinessType();
$scope.ClearBusinessTypeForm();
alert("Record Updated Successful");
$scope.BusinessTypeAction = "";
$scope.divBusinessType = false;
}, function () {
alert('Error in Updating Record');
});
} else {
**// Save Section**
var getExistBusinessCode = businessTypeService.checkBusinessTypeCode(businessType.Code);
getExistBusinessCode.then(function (businessTypeCode) {
debugger;
if (businessTypeCode == true) {
alert('Business Type Code Already Exist');
} else {
debugger;
var getBusinessTypeData = businessTypeService.addBusinessType(businessType);
getBusinessTypeData.then(function (msg) {
GetAllBusinessType();
$scope.ClearBusinessTypeForm();
alert("Record Added Successful");
$scope.divBusinessType = false;
}, function () {
alert("Error Occured In Saving Data");
});
}
},function() {
alert('Error Occured While Checking Records');
});
}
}
In the above code Save Section I am trying to check if a value is exists in a database so I'm passing a string value to: checkBusinessTypeCode(businessType.Code) Service.When I Debug and See Value its Seems Normal.
Here's My Service:
//Check Business Code
this.checkBusinessTypeCode = function (businessTypeCode) {
debugger;
var response = $http({
method: "post",
url: "/BusinessType/CheckBusinessTypeDetailByCode",
params: {
businessTypeCode: JSON.stringify(businessTypeCode)
}
});
return response;
}
But when Passing To Controller string value I get some unexpected behavior.
two \\ always appear automatically
example
"\"stringvalue\""
I'm Still Having Above Problem
but as a quick solution i did code as follows
public bool _CheckBusinessTypeDetailByCode(string businessTypeCode)
{
string bisCode = businessTypeCode.Replace("\"", "");
bool isExist;
isExist = _IBusinessTypeRepository.IsExist(x => x.IsActive && !x.IsDelete && x.Code == bisCode);
return isExist;
}
I don't know is it bad practice or not , any way it is solved my problem.
Before did this modification
string businessTypeCode always gives value as
"\"somevalue\""

Code 141 (error: success/error was not called) on Parse Cloud Code nested queries

Background:
I have a Parse database of images. Simply, my code does this:
A user, through a Parse Cloud call requests an image ("getNewPicture"). Nested within I check if he has seen any pictures before (alongside other requirements) and if so deliver one specific picture (getSpecifiedPicture). If he has not, then I deliver a new picture (getNewPicture).
Issue:
Calling "getNewPicture" through Parse Cloud Code function I get an error code 141. What's strange is that it works through Android but not iOS.
My code:
Parse.Cloud.define("getNewPicture", function(request, response) {
var SeenPictures = Parse.Object.extend("SeenPictures");
var query = new Parse.Query(SeenPictures);
var username = request.params.username;
var notWantedPics = [];
query.ascending("createdAt");
query.equalTo("username", username);
query.find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
if (results[i].get("likes") == 1 || results[i].get("dislikes") == 1) {
notWantedPics.push(results[i].get("pictureId"));
results.splice(i, 1);
i--;
}
}
if (results != 0) {
getSpecifiedPicture(results[0].get("pictureId"), {
success: function(returnValue) {
response.success(returnValue);
},
error: function(error) {
response.error(error);
}
});
} else {
getNewPicture(username, notWantedPics, {
success: function(returnValue) {
response.success(returnValue);
},
error: function(error) {
response.error(error);
}
});
}
},
error: function() {
response.error(error);
}
});
});
function getSpecifiedPicture(specifiedPic, callback) {
var Pictures = Parse.Object.extend("Pictures");
var pictures = new Parse.Query(Pictures);
pictures.get(specifiedPic, {
success: function(picture) {
callback.success(picture);
},
error: function(error) {
callback.error(error);
}
});
}
function getNewPicture(username, notWantedPics, callback) {
var Pictures = Parse.Object.extend("Pictures");
var pictures = new Parse.Query(Pictures);
pictures.notEqualTo("photographerUserName", username);
pictures.notContainedIn("objectId", notWantedPics);
pictures.ascending("createdAt");
pictures.find({
success: function(results) {
if (results.length > 0) {
var object = results[0];
//Some other fancy stuff
object.save();
callback.success(object);
}
},
error: function(error) {
callback.error(error);
}
});
}
Why am I getting code 141? Any help is appreciated.
Thanks.
Your callbacks are a mess. I rewrote it to follow more of a promise chain style. Much easier to follow. Also, underscore.js is your friend. Hopefully I got your idea right.
var _ = require('underscore'); // Javascript Library
Parse.Cloud.define("getNewPicture", function(request, response) {
var username = request.params.username;
var notWantedPics = [];
if (!username) {
return response.error('No username.');
}
var query1 = new Parse.Query("SeenPictures");
query1.ascending("createdAt");
query1.equalTo("username", username);
var SeenPictures = query1.find();
return Parse.Promise.when([SeenPictures]).then(function (SeenPictures) {
SeenPictures = _.filter(SeenPictures, function (SeenPicture) {
if (SeenPicture.get("likes") == 1 || SeenPicture.get("dislikes") == 1) {
notWantedPics.push(SeenPicture.get("pictureId"));
return false;
}
else {
return true;
}
});
// notWantedPics?
if (SeenPictures > 0) {
var query2 = new Parse.Query("Pictures");
var Pictures = [query2.get(SeenPictures[0].get('pictureId'))];
}
else {
var query2 = new Parse.Query("Pictures");
query2.notEqualTo("photographerUserName", username);
query2.notContainedIn("objectId", notWantedPics);
query2.ascending("createdAt");
var Pictures = query2.find();
}
return Parse.Promise.when([Pictures]);
}).then(function (Pictures) {
if (Pictures > 0) {
// Success
return response.success(Pictures[0]);
} else {
return Parse.Promise.error("No pictures.");
}
}, function (error) {
// Error
return response.error(error);
});
});

Resources