Objective-C将NSURL传递给另一个viewcontroller

时间:2014-01-16 06:38:53

标签: ios objective-c viewcontroller nsurl

我有两个视图控制器:FirstViewControllerSecondViewController。该项目是录制视频并将其附加到电子邮件。我可以录制它并让它能够发送电子邮件,我只需要附上它。我可以在FirstViewController中获取视频的网址,但是通过该网址无效。

FirstViewController -

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{

    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    if ([mediaType isEqualToString:@"public.movie"])
    {
       // Saving the video to phone / // Get the new unique filename
       NSString *sourcePath = [[info objectForKey:@"UIImagePickerControllerMediaURL"]relativePath];

       UISaveVideoAtPathToSavedPhotosAlbum(sourcePath, self, /*@selector(video:didFinishSavingWithError:contextInfo:)*/nil, nil);
       self.movieURL= [[NSURL alloc] initFileURLWithPath: sourcePath];
       NSLog(@"movieURL");
       NSLog(self.movieURL.absoluteString);

       SecondViewController *sendMovie = [[SecondViewController alloc] initWithNibName:@"ViewController" bundle:nil];
       sendMovie.movieU = [[NSURL alloc] initFileURLWithPath: sourcePath];
       [[self navigationController] pushViewController:sendMovie animated:YES];

       NSLog(@"movieU");
       NSLog(sendMovie.movieU.absoluteString);
   }

   [picker dismissViewControllerAnimated:YES completion:NULL];
}

SecondViewController 附加到电子邮件 -

NSLog(@"1st print");
NSLog(self.movieU);
[controller addAttachmentData:[NSData dataWithContentsOfURL:self.movieU] mimeType:@"video/MOV" fileName:@"defectVideo.MOV"];
NSLog(@"2nd print");
NSLog(self.movieU.absoluteURL);
[self presentViewController:controller animated:YES completion:nil];
NSURL的

SecondViewController.h 属性

@property(nonatomic) NSURL *movieU; 

movieURLFirstViewController中的属性,但我认为不需要。

我可以在FirstVC中看到该网址,但在SecondVC中显示为零。

4 个答案:

答案 0 :(得分:2)

解决方案 -

1)将NSURL *movieU定义为extern而不是属性。

2)否则将其定义为AppDelegate的属性并访问它。

3)或synthesize属性movieU并分配如 -

FirstViewController -

 SecondViewController *sendMovie = [[SecondViewController alloc] initWithNibName:@"ViewController" bundle:nil];
 NSURL *url = [[NSURL alloc] initFileURLWithPath: sourcePath];
 sendMovie.movieU = url;
 [[self navigationController] pushViewController:sendMovie animated:YES];

NSLog SecondViewController

希望这有帮助!

答案 1 :(得分:1)

您传递信息的方式没有任何问题。试试这个:

    // In you code where you create the second view controller.
    SecondViewController *sendMovie = [[SecondViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    // SecondViewController viewDidLoad method being called (movieU is still nil)

    sendMovie.movieU = [[NSURL alloc] initFileURLWithPath: sourcePath]; 

    // Do a nil test here
    if (!sendMovie.movieU) {
        NSLog(@"%@",@"It's nil here!"); // If this is the case something is wrong with "sourcePath"
    } else {
        NSLog(@"%@",@"It's not nil here!");
    }

    [[self navigationController] pushViewController:sendMovie animated:YES];
    // SecondViewController viewWillAppear method being called (movieU is NOT nil)
    // SecondViewController viewDidAppear method being called (movieU is NOT nil)

这个测试会告诉你很多。如果它在这里为零则问题不在于设置第二个视图控制器的属性,而是实际创建NSURL对象。它可能是很多东西,比如你在第二个视图控制器中的某处覆盖它(例如viewWillAppear方法)。只需使用断点,记录等跟踪其跟踪其生命周期。

编辑 - 调试程序

设置创建第二个VC的断点,设置其属性,推送它,最后查看它(单击选项卡)。在第二个VC(viewDidLoadviewWillAppearviewDidAppear等生命周期的整个生命周期中设置断点。这将允许您逐步完成VC的整个生命周期。如果您还没有使用这些方法,请继续定义它们,包括调用super。当您逐步浏览这些断点时,请继续检查movieU的值。一开始你会看到它是零,然后你设置它(我们从你的评论中知道这一点),它不是零,然后再变为零,等等。如果你有耐心和系统性,你会发现它并学到很多东西关于风险投资的生命周期。如果你没有系统地介入,你可能会错过一些东西。例如,当您单击选项卡以实际查看它时,您的代码可能正在创建一个全新的第二个VC。以这种方式单步执行代码将显示。

修改

确保使用viewWillAppear / viewDidAppear方法或更高版本进行测试,以便实际设置该属性。请参阅我的代码中的评论。

修改

  

在没有所有权来源的情况下合成的可保留对象指针类型的属性具有其关联实例变量的所有权(如果已存在);否则,[开始Apple 3.1,LLVM 3.1]其所有权隐含强大。在此次修订之前,合成这样的财产是不合理的。

来自:http://clang.llvm.org/docs/AutomaticReferenceCounting.html#property-declarations

根据这个(除非你在ivar上指定弱点 - 不太可能),默认情况下它应该很强。

祝你好运。

答案 2 :(得分:0)

使用此

self.movieURL = [NSURL fileURLWithPath:sourcePath];

而不是

self.movieURL= [[NSURL alloc] initFileURLWithPath: sourcePath];

希望这项工作

答案 3 :(得分:0)

我修好了!我决定使用一个单例,它通过另一个类使用共享实例。我创建了一个名为Singleton的全新类,只包含了sharedinstance方法:

+ (id)sharedInstance {
static id sharedInstance = nil;
if (sharedInstance == nil) {
    sharedInstance = [[self alloc] init];
}
return sharedInstance;
}

Singleton.h

 @property NSURL *movieU;
 + (id)sharedInstance;

确保将singleton类导入第一个和第二个VC。

SecondVC.m

Singleton* single = [Singleton sharedInstance];
[controller addAttachmentData:[NSData dataWithContentsOfURL: single.movieU] mimeType:@"video/MOV" fileName:@"defectVideo.MOV"];

FirstVC.m

Singleton* single = [Singleton sharedInstance];

NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:@"public.movie"]){
    // Saving the video / // Get the new unique filename
    NSString *sourcePath = [[info objectForKey:@"UIImagePickerControllerMediaURL"]relativePath];
    UISaveVideoAtPathToSavedPhotosAlbum(sourcePath, self, /*@selector(video:didFinishSavingWithError:contextInfo:)*/nil, nil);
    self.movieURL = [[NSURL alloc] initFileURLWithPath: sourcePath];
    NSLog(@"movieURL");
    single.movieU = self.movieURL;

通过这样做,它成功地传递了包含要附加到电子邮件的录制视频的信息的URL。