I'm doing a app which takes input from the user and generates PDF file.i"m trying to upload generated pdf file to api.but, i'm not getting how to do it, i'm totally new to swift.can anyone please give me a exsample on how to upload a file to api
Thanks in advance
First, I'd suggest you consider using Alamofire if you don't want to get lost in the idiosyncrasies of composing network requests. If you do it yourself, it can get pretty hairy (see https://stackoverflow.com/a/26163136/1271826 for example of how to construct multipart/formdata request manually).
Second, in terms of how that request should be formed, it depends entirely upon how you designed the API. But the easiest for file uploads is to support multipart/formdata requests (e.g. in PHP, using the $_FILES mechanism). See http://php.net/manual/en/features.file-upload.php. Or see example here that not only uploads image file (which you can easily modify to accept PDFs), but constructs JSON response, too: https://stackoverflow.com/a/19743872/1271826.
Anyway, if your server is designed to handle multipart/formdata requests, you can create request and parse the response using Alamofire, as shown in the Uploading MultipartFormData section of the README file:
Alamofire.upload(
.POST,
"https://httpbin.org/post",
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(fileURL: unicornImageURL, name: "unicorn")
multipartFormData.appendBodyPart(fileURL: rainbowImageURL, name: "rainbow")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .Failure(let encodingError):
print(encodingError)
}
}
)
Related
I am working in a mobile app. In this mobile app I need to send a file (.wav file) to a server.
At this moment, I am working locally and testing my app. I am creating an audio file in the mobile app with a defined name and extension. However, I'm wondering, If my app is used by more people,
can it happen that, if the different users use the app and send the file at the same time, as the file name is already defined in the app, in the server this file is going to be overwitten ?
What is usually the behaviour in a situation like this? And if the file is overwitten, how can I overcome this problem, since diffrent users may send a different file?
Details:
API : FAST API :
async def something(file: UploadFile = File(...)):
with open(f"{file.filename}", "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
#saved teh file
developing with React NAtive
Using Expo AV to do the audio
sending the audio using fetch
sending method:
formData.append("file",
uri: path,
name: "audio.wav",
type: "audio/wav",
....
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
},
body: formData,
Thanks !
This scenario should be handled completely by the server. The client should not contain any logic on what files are already located on the server and which are not.
Let the server create a new uuid for each new file that it receives.
Thus, the metadata for a file upload could be the following object.
{
uuid: "11edc52b-2918-4d71-9058-f7285e29d894",
fileUri: "",
}
Thus, the server needs to be adapted to solve this problem. The file is then stored along with its unique identifier. No name clash should occur.
Of course, if you want to display the files in the client later, then you need some name property, which could be the fileUri appended with a counter variable if the same fileUri exists multiple times. This should be handled by the server as well.
In my node.js application I'm downloading multiple user files from AWS S3, compress them to single zip (with usage of Archiver npm library) file and send back to client. All the way I'm operating on streams, and yet I can't send files to client (so client would start download after successful http request).
const filesStreams = await this.awsService.downloadFiles(
document?.documentFiles,
);
const zipStream = await this.compressService.compressFiles(filesStreams);
// ts-ignore
response.setHeader('Content-Type', 'application/octet-stream');
response.setHeader(
'Content-Disposition',
'attachment; filename="files.zip"',
);
zipStream.pipe(response);
Where response is express response object. zipStream is created with usage of Archiver:
public async compressFiles(files: DownloadedFileType[]): Promise<Archiver> {
const zip = archiver('zip');
for (const { stream, name } of files) {
zip.append((stream as unknown) as Readable, {
name,
});
}
return zip;
And I know it is correct - because when I pipe it into WriteStream to some file in my file system it works correctly (I'm able to unzip written file and it has correct content). Probably I could temporarily write file in file system, send it back to client with usage of response.download and remove save file afterwards, but it looks like very inefficient solution. Any help will be greatly appreciated.
So I found a source of a problem - I'll post it here just for record, in case if anyone would have same problem. Source of the problem was something totally different - I was trying to initiate a download by AJAX request, which of course won't work. I changed my frontend code and instead AJAX I used HTML anchor element with src attribute set on exactly same endpoint and it worked just fine.
I had a different problem, but rather it came from the lint. I needed to read all files from the directory, and then send them to the client in one zip. Maybe someone finds it useful.
There were 2 issues:
I mismatched cwd with root; see glob doc
Because I used PassThrough as a proxy object between Archiever and an output, lint shows stream.pipe(response) and type issue... what is a mistake - it works fine.
Is it possible (or advisable) to have a single API endpoint that will return a json object with data OR download a file? I'm using axios and vue.js on the UI and Asp.Net Core 2.2 on the API. Details on why I want to do this:
I'm generating a file from the server on request. Happy path has these files being uploaded to SharePoint from the server, and the resulting document URL sent back to the client. The client will read this url and get it to download and check out the file. If the document could not be uploaded to SharePoint, I would still like to send the file to the client for direct download/save. I would rather not do this in two requests (get the results, then either download via the SharePoint URL, or request the document from the server) because I don't want to persist that document between requests. I am able to use axios to write the byte array to a file, I just don't know how to optionally read the response for the URL of the document, OR just write the byte stream as a file.
For return different response types, you could try return IActionResult instead of the specific response type.
Try something like
[HttpPost]
public IActionResult Upload(int id, IFormFile file)
{
if (id == 1)
{
return Ok("file path");
}
else
{
return File(file.OpenReadStream(), file.ContentType);
}
}
I have just 3 variables and posting using postman to sever.
I need a solution to parse just form-data text in Express JS
When I searched in net, I see people just suggested that,
We cant use body-parser to handle form-data and need to use multer, busboy, multiparty
Also people suggest if not sending files need not use multer and formidable.
But can anyone explain how exactly to use this with node js. When I see modules github, i am not able to understand to use it for my needs.
https://stackoverflow.com/a/36199881/5078763
I know setting x-www-form-urlencoded option in postman works but I need for form-data
app.post('/addUsrForm', addUsrFnc);
function addUsrFnc(req, res)
{
console.log("Data Received : ");
var namUserVar =
{
nameKey: req.body.nameKey,
mailKey: req.body.mailKey,
mobileKey: req.body.mobileKey
};
console.log(NquUsrJsnObjVar);
}
This answer provides good detailing of the different use cases for html form encoding. What does enctype='multipart/form-data' mean?
x-www-form-urlencoded is the default.
multipart/form-data is for larger data sends, such as entire files.
Postman settings aside, if your server needs to handle multipart/form-data, install multer and use it like so...
if just sending text fields in a multipart/form-data encoding:
var multer = require('multer')
var multParse = multer()
...
function handler(req, res) {
// fields will be parsed in req.body
}
...
app.post('/', multParse.none(), handler)
Follow the multer api on the multer github page if you actually are sending files and not just text fields.
I've run into the following problem when porting an app from REST API to GDAA.
The app needs to download some of (thousands of) JPEG images based on user selection. The way this is solved in the app is by downloading a thumbnail version first, using this construct of the REST API:
private static InputStream getCont(String rsid, boolean bBig){
InputStream is = null;
if (rsid != null) try {
File gFl = bBig ?
mGOOSvc.files().get(rsid).setFields("downloadUrl" ).execute():
mGOOSvc.files().get(rsid).setFields("thumbnailLink").execute();
if (gFl != null){
GenericUrl url = new GenericUrl(bBig ? gFl.getDownloadUrl() : gFl.getThumbnailLink());
is = mGOOSvc.getRequestFactory().buildGetRequest(url).execute().getContent();
}
} catch (UserRecoverableAuthIOException uraEx) {
authorize(uraEx.getIntent());
} catch (GoogleAuthIOException gauEx) {}
catch (Exception e) { }
return is;
}
It allows to get either a 'thumbnail' or 'full-blown' version of an image based on the bBig flag. User can select a thumbnail from a list and the full-blown image download follows (all of this supported by disk-base LRU cache, of course).
The problem is, that GDAA does not have an option to ask for reduced size / thumbnail version of an object (AFAIK), so I have to resort to combining both APIs, which makes the code more convoluted then I like (bottom of the page). Needles to state that the 'Resource ID' needed by the REST may not be immediately available.
So, the question is: Is there a way to ask GDAA for a 'thumbnail' version of a document?
Downloading thumbnails isn't currently available in the Drive Android API, and unfortunately I can't give a timeframe to when it will be available. Until that time, the Drive Java Client Library is the best way to get thumbnails on Android.
We'd appreciate if you go ahead and file a feature request against our issue tracker: https://code.google.com/a/google.com/p/apps-api-issues/
That gives requests more visibility to our teams internally, and issues will be marked resolved when we release updates.
Update: I had an error in the discussion of the request fields.
As Ofir says, you can't get thumbnails with the Drive Android API and you can get thumbnails with the Drive Java Client Library. This page has is a really good primer for getting started:
https://developers.google.com/drive/v3/web/quickstart/android
Oddly, I can't get the fields portion of the request to work as it is on that quick start. As I've experienced, you have to request the fields a little differently.
Since you're doing a custom field request you have to be sure to add the other fields you want as well. Here is how I've gotten it to work:
Drive.Files.List request = mService.files()
.list()
.setFields("files/thumbnailLink, files/name, files/mimeType, files/id")
.setQ("Your file param and/or mime query");
FileList files = request.execute();
files.getFiles(); //Each File in the collection will have a valid thumbnailLink
A sample query might be:
"mimeType = 'image/jpeg' or mimeType = 'video/mp4'"
Hope this helps!