1

Requirement: We are able to make connection from host device to multiple slave devices. For example, if device A initiate connection to device B and C, the contributor devices can accept peer connection and connected to device A. Here A is master device and B and C are contributors device. Now if B share their songs to A, A can play songs and see songs information. In meantime C will be idle but should connected. When B will finish to play songs, then C can also able to share their songs to device A.

Here are the problem that we have faced to achieve above tasks: 1. As soon as B started sharing songs to A, C got crashed. But A still able to play song shared by B.

array = [[NSMutableArray alloc] initWithObjects:[self.session connectedPeers], nil];
[_session sendData:[NSKeyedArchiver archivedDataWithRootObject:[info mutableCopy]]  toPeers:[array objectAtIndex:0] withMode:MCSessionSendDataUnreliable error: &error];
NSLog(@"localizedDescription %@",error);    
  1. To overcome from this problem directly pass array without index here toPeers:array. It is working and we are able to share and play songs with device A, but song information not receive to device A.

Here are full code that we are using: contributor Controller :

    - (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
    [self dismissViewControllerAnimated:YES completion:nil];
    someMutableArray = [mediaItemCollection items];
        counter = 0;
    if(someMutableArray.count>1){
        BOOL isselectsongone=YES;
        [[NSUserDefaults standardUserDefaults] setBool:isselectsongone forKey:@"isselectsongone"];
    }
    [self showSpinner];
        [self someSelector:nil];


     }

- (void)someSelector:(NSNotification *)notification {
    if(notification && someMutableArray.count>1 && counter <someMutableArray.count-1){
        NSDate *start = [NSDate date];

        counter=counter+1;
         [self.outputStreamer stop];
         self.outputStreamer = nil;
         self.outputStream = nil;

    }
        song=[someMutableArray objectAtIndex:counter];
    NSMutableDictionary *info = [NSMutableDictionary dictionary];

    info=[[NSMutableDictionary alloc] init];
    info[@"title"] = [song valueForProperty:MPMediaItemPropertyTitle] ? [song valueForProperty:MPMediaItemPropertyTitle] : @"";
    info[@"artist"] = [song valueForProperty:MPMediaItemPropertyArtist] ? [song valueForProperty:MPMediaItemPropertyArtist] : @"";
    //NSNumber *duration=[song valueForProperty:MPMediaItemPropertyPlaybackDuration];

    int fullminutes = floor([timeinterval floatValue] / 60); // fullminutes is an int
    int fullseconds = trunc([duration floatValue] - fullminutes * 60);  // fullseconds is an int

    [NSTimer scheduledTimerWithTimeInterval:[duration doubleValue]target:self selector:@selector(getdata) userInfo:nil repeats:YES];

   }

-(void)getdata {
    NSMutableDictionary *info = [NSMutableDictionary dictionary];
    info=[[NSMutableDictionary alloc] init];
    info[@"title"] = [song valueForProperty:MPMediaItemPropertyTitle] ? [song valueForProperty:MPMediaItemPropertyTitle] : @"";
    info[@"artist"] = [song valueForProperty:MPMediaItemPropertyArtist] ? [song valueForProperty:MPMediaItemPropertyArtist] : @"";
    NSNumber *duration=[song valueForProperty:MPMediaItemPropertyPlaybackDuration];

    int fullminutes = floor([duration floatValue] / 60); // fullminutes is an int
    int fullseconds = trunc([duration floatValue] - fullminutes * 60);  // fullseconds is an int

    info[@"duration"] = [NSString stringWithFormat:@"%d:%d", fullminutes, fullseconds];

    MPMediaItemArtwork *artwork = [song valueForProperty:MPMediaItemPropertyArtwork];

    UIImage *image = [artwork imageWithSize:CGSizeMake(150, 150)];
    NSData * data = UIImageJPEGRepresentation(image, 0.0);
    image = [UIImage imageWithData:data];



    array = [[NSMutableArray alloc] initWithObjects:[self.session connectedPeers], nil];
    MCPeerID* peerID11 = self.session.myPeerID;
    NSMutableArray *arr=[[NSMutableArray alloc] initWithObjects:peerID11, nil];
    NSLog(@"%@",arr);
    if (image)
        self.songArtWorkImageView.image = image;
    else
        self.songArtWorkImageView.image = nil;

    self.songTitleLbl.text = [NSString stringWithFormat:@"%@ \n[Artist : %@]", info[@"title"], info[@"artist"]];

    NSError *error;

    [_session sendData:[NSKeyedArchiver archivedDataWithRootObject:[info mutableCopy]]  toPeers:[array objectAtIndex:0] withMode:MCSessionSendDataUnreliable error: &error];
    NSLog(@"localizedDescription %@",error);



    @try {
        if(_session && _session.connectedPeers && [_session.connectedPeers count] > 0)   {

            NSLog(@"%@",[song valueForProperty:MPMediaItemPropertyAssetURL]);
                    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[song valueForProperty:MPMediaItemPropertyAssetURL] options:nil];

                    [self convertAsset: asset complition:^(BOOL Success, NSString *filePath) {
                        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                            if(Success) {

                                                              if(image)   {
                                    [self saveImage: image withComplition:^(BOOL status, NSString *imageName, NSURL *imageURL) {
                                        if(status)  {
                                            @try {

                                                [_session sendResourceAtURL:imageURL withName:imageName toPeer:[_session.connectedPeers objectAtIndex:0]withCompletionHandler:^(NSError *error) {
                                                    if (error) {
                                                        NSLog(@"Failed to send picture to %@", error.localizedDescription);
                                                        return;
                                                    }
                                                    //Clean up the temp file
                                                    NSFileManager *fileManager = [NSFileManager defaultManager];
                                                    [fileManager removeItemAtURL:imageURL error:nil];
                                                }];

                                            }
                                            @catch (NSException *exception) {

                                            }
                                        }
                                    }];
                                }
                                              @try {
                                                   [self hideSpinner];
                                    if(!self.outputStream)  {
                                        NSArray * connnectedPeers = [_session connectedPeers];
                                        if([connnectedPeers count] != 0)    {
                                            [self outputStreamForPeer:[_session.connectedPeers objectAtIndex:0]];
                                        }
                                    }
                                }
                                @catch (NSException *exception) {

                                }
                                if(self.outputStream)    {

                                        self.outputStreamer = [[TDAudioOutputStreamer alloc] initWithOutputStream:self.outputStream];
//
                                    [self.outputStreamer initStream:filePath];
                                    NSLog(@"%@",filePath);
                                    if(self.outputStreamer)    {
                                    [self.outputStreamer start];

                                    }

                                    else{
                                        NSLog(@"Error: output streamer not found");

                                    }

                                }
                                else{
                                    //self.outputStream=[[NSOutputStream alloc] init];
                                    self.outputStreamer = [[TDAudioOutputStreamer alloc] initWithOutputStream:self.outputStream];
                                    [self.outputStreamer initStream:filePath];
                                    NSLog(@"%@",filePath);
                                    if(self.outputStreamer)    {

                                        [self.outputStreamer start];

                                    }


                                }

                            }
                            else    {
                                [UIView showMessageWithTitle:@"Error!" message:@"Error occured!" showInterval:1.5];
                            }


                        });
                    }];

              // }

        }
    }

    @catch (NSException *exception) {
        NSLog(@"Expection: %@", [exception debugDescription]);
    }
//}
}

HostViewcontroller :

    - (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID
{

    NSLog(@"%@",peerID);
    NSLog(@"sessions%@",session);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        @try {
        // NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:data];
           info = [NSKeyedUnarchiver unarchiveObjectWithData:data];
            self.songTitleLbl.text = [NSString stringWithFormat:@"%@ \n[Duration: %@] [Artist : %@] ", info[@"title"], info[@"duration"], info[@"artist"]];
            NSLog(@"eeret%@",self.songTitleLbl.text);
            self.songArtWorkImageView.image = nil;
            [self showSpinner];
        }
        @catch (NSException *exception) {
            self.songTitleLbl.text = @"Some error occured...\nPlease try again";
            self.songArtWorkImageView.image = nil;
        }
    });
}

Please let us know if I have missed anything here or the better way to achieve the above requirement. Any help really appreciated.

Neha
  • 63
  • 12
  • You are sending stream for music files and you are calling didReceiveData delegate for the MCSession, did you tried to called didReceiveStream instead ? – Aadil Keshwani May 06 '16 at 05:18
  • Yes didReceiveData is using for songs property ,btw i found a solution actually we need to use all delegate methods on contributor side also . – Neha May 06 '16 at 07:56

0 Answers0