seguridad - restaurar whatsapp desde google drive en iphone
Subiendo video con iPhone (4)
Editado en agosto de 2015
Esta respuesta ahora está seriamente desactualizada. En el momento de escribir, no había muchas opciones y los videos eran relativamente pequeños. Si está considerando hacer esto ahora, usaría AFNetworking
que hace que esto sea mucho más simple. Transmitirá la carga desde el archivo en lugar de mantenerlo todo en la memoria, y también es compatible con la nueva tarea de carga en segundo plano de Apple.
Documentos aquí: https://github.com/AFNetworking/AFNetworking#creating-an-upload-task
-
Sí, esto es posible y así es como lo hice.
Implemente la siguiente función que se ejecuta cuando el selector de medios finaliza.
- (NSData *)generatePostDataForData:(NSData *)uploadData
{
// Generate the post header:
NSString *post = [NSString stringWithCString:"--AaB03x/r/nContent-Disposition: form-data; name=/"upload[file]/"; filename=/"somefile/"/r/nContent-Type: application/octet-stream/r/nContent-Transfer-Encoding: binary/r/n/r/n" encoding:NSASCIIStringEncoding];
// Get the post header int ASCII format:
NSData *postHeaderData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Generate the mutable data variable:
NSMutableData *postData = [[NSMutableData alloc] initWithLength:[postHeaderData length] ];
[postData setData:postHeaderData];
// Add the image:
[postData appendData: uploadData];
// Add the closing boundry:
[postData appendData: [@"/r/n--AaB03x--" dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
// Return the post data:
return postData;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
//assign the mediatype to a string
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
//check the media type string so we can determine if its a video
if ([mediaType isEqualToString:@"public.movie"]){
NSLog(@"got a movie");
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *webData = [NSData dataWithContentsOfURL:videoURL];
[self post:webData];
[webData release];
}
para la función de publicación tuve algo así que obtuve de otro lado (lo siento, no sé dónde lo encontré):
- (void)post:(NSData *)fileData
{
NSLog(@"POSTING");
// Generate the postdata:
NSData *postData = [self generatePostDataForData: fileData];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
// Setup the request:
NSMutableURLRequest *uploadRequest = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.example.com:3000/"] cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 30 ] autorelease];
[uploadRequest setHTTPMethod:@"POST"];
[uploadRequest setValue:postLength forHTTPHeaderField:@"Content-Length"];
[uploadRequest setValue:@"multipart/form-data; boundary=AaB03x" forHTTPHeaderField:@"Content-Type"];
[uploadRequest setHTTPBody:postData];
// Execute the reqest:
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:uploadRequest delegate:self];
if (conn)
{
// Connection succeeded (even if a 404 or other non-200 range was returned).
NSLog(@"sucess");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Got Server Response" message:@"Success" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
else
{
// Connection failed (cannot reach server).
NSLog(@"fail");
}
}
El fragmento de arriba crea la solicitud de HTTP y la envía. Tendrá que modificarlo si desea un manejo de errores decente y considerar el uso de una biblioteca que permita la carga asíncrona (hay uno en github)
También tenga en cuenta el puerto: 3000 en la URL del servidor anterior, encontré que es fácil para la prueba de errores iniciar un servidor de rieles en su puerto predeterminado 3000 en modo de desarrollo para poder ver los parámetros de solicitud con fines de depuración
Espero que esto ayude
¿Es posible subir video a un servidor? Sé que las imágenes son posibles. Si alguien puede simplemente señalarme en la dirección correcta, sería increíble.
Gracias
Eche un vistazo al UIImagePickerController. A partir de 3.0, puede permitir que elija grabar un video o elegir un video existente. De acuerdo con los documentos, está limitado a 10 minutos como máximo en la película:
NSURL *urlvideo = [info objectForKey:UIImagePickerControllerMediaURL];
NSString *urlString=[urlvideo path];
NSLog(@"urlString=%@",urlString);
NSString *str = [NSString stringWithFormat:@"you url of server"];
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setFile:urlString forKey:@"key foruploadingFile"];
[request setRequestMethod:@"POST"];
[request setDelegate:self];
[request startSynchronous];
NSLog(@"responseStatusCode %i",[request responseStatusCode]);
NSLog(@"responseStatusCode %@",[request responseString]);
Desde iOS8 no es necesario utilizar bibliotecas de terceros y puede transmitir video directamente desde el archivo que soluciona el ERROR DE FUERA DE LA MEMORIA crucial cuando intenta subir videos más grandes mientras los carga desde el archivo:
// If video was returned by UIImagePicker ...
NSURL *videoUrl = [_videoDictionary objectForKey:UIImagePickerControllerMediaURL];
NSMutableURLRequest *request =[[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:VIDEO_UPLOAD_LINK]];
[request addValue:@"video" forHTTPHeaderField: @"Content-Type"];
[request setHTTPMethod:@"POST"];
NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:[videoUrl path]];
[request setHTTPBodyStream:inputStream];
self.uploadConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
iOS7 también ofrece la gran solución combinada NSURLSeession / NSURLSessionUploadTask , que no solo te permite transmitir directamente desde el archivo, sino que también puede delegar tareas al proceso de iOS, lo que permitirá que la carga finalice incluso cuando tu aplicación esté cerrada . Requiere un poco más de codificación y no tengo tiempo para escribirlo todo aquí (puedes buscarlo en Google).
Estas son las partes más importantes:
Configué sesión de audio en soporte de fondo:
- (NSURLSession *) urlSession {
if (!_urlSession) { NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; NSString *bundleId = infoDict[@"CFBundleIdentifier"]; NSString *label = [NSString stringWithFormat:@"ATLoggerUploadManager_%@", bundleId]; NSURLSessionConfiguration *conf = (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) ? [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:label] : [NSURLSessionConfiguration backgroundSessionConfiguration:label]; conf.allowsCellularAccess = NO; _urlSession = [NSURLSession sessionWithConfiguration:conf delegate:self delegateQueue:self.urlSessionQueue]; _urlSession.sessionDescription = @"Upload log files"; } return _urlSession;
}
Método de carga de la carga:
- (NSURLSessionUploadTask *) uploadTaskForFilePath: (NSString *) sesión filePath: (NSURLSession *) session {
NSFileManager *fm = [NSFileManager defaultManager]; NSError *error = nil; // Consruct request: NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setHTTPMethod:@"POST"]; NSString *finalUrlString = [self.uploadURL absoluteString]; if (self.uploadUserId) { [request setValue:self.uploadUserId forHTTPHeaderField:@"X-User-Id"]; finalUrlString = [finalUrlString stringByAppendingFormat:@"?id=%@", self.uploadUserId]; } [request setURL:[NSURL URLWithString:finalUrlString]]; /* It looks like this (it only works if you quote the filename): Content-Disposition: attachment; filename="fname.ext" */ NSString *cdh = [NSString stringWithFormat:@"attachment; filename=/"%@/"", [filePath lastPathComponent]]; [request setValue:cdh forHTTPHeaderField:@"Content-Disposition"]; error = nil; unsigned long fileSize = [[fm attributesOfItemAtPath:filePath error:&error] fileSize]; if (!error) { NSString *sizeInBytesAsString = [NSString stringWithFormat:@"%lu", fileSize]; [request setValue:sizeInBytesAsString forHTTPHeaderField:@"X-Content-Length"]; } NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileUrl]; uploadTask.taskDescription = filePath; return uploadTask;
}
Función de carga:
[self.urlSession getTasksWithCompletionHandler: ^ (NSArray * dataTasks, NSArray * uploadTasks, NSArray * downloadTasks) {
NSMutableDictionary *tasks = [NSMutableDictionary new]; int resumed_running_count = 0; int resumed_not_running_count = 0; int new_count = 0; // 1/2. Resume scheduled tasks: for(NSURLSessionUploadTask *task in uploadTasks) { //MILogInfo(@"Restored upload task %zu for %@", (unsigned long)task.taskIdentifier, task.originalRequest.URL); if (task.taskDescription) { [tasks setObject:task forKey:task.taskDescription]; } BOOL isRunning = (task.state == NSURLSessionTaskStateRunning); if (!isRunning) { resumed_not_running_count++; }else{ resumed_running_count++; } [task resume]; } // 2/2. Add tasks / files not scheduled yet: NSString *uploadFilePath = nil; // already uploading: if (![tasks valueForKey:uploadFilePath]) { NSURLSessionUploadTask *uploadTask = [self uploadTaskForFilePath:uploadFilePath session:_urlSession]; new_count++; [uploadTask resume]; } }];
La sesión de fondo requiere un delegado de UIApplecation (devolución de llamada de AppDelegate implementada:
(void) application: aplicación (UIApplication *) handleEventsForBackgroundURLSession: (NSString *) identifier completionHandler: (void (^) ()) completionHandler {
NSLog(@"Background URL session needs events handled: %@", identifier); completionHandler();
}