Transcript
Page 1: Synchronizing without internet - Multipeer Connectivity (iOS)

Synchronizingwithout internetCodemotion 2014, Madrid

Page 2: Synchronizing without internet - Multipeer Connectivity (iOS)

Who am I?Jorge Maroto (@patoroco)

http://maroto.me

· iOS Developer @ticketeaeng

· Playing with iOS since 2010

· Fanboy

Page 3: Synchronizing without internet - Multipeer Connectivity (iOS)

Synchronize

Page 4: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 5: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 6: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 7: Synchronizing without internet - Multipeer Connectivity (iOS)

¿Internet?

Page 8: Synchronizing without internet - Multipeer Connectivity (iOS)

LAN (wired / wi-fi)

Page 9: Synchronizing without internet - Multipeer Connectivity (iOS)

What about iOS?

Page 10: Synchronizing without internet - Multipeer Connectivity (iOS)

Changelog· iOS 3: Game Kit

· iOS 4: Game Center· iOS 5: Core Bluetooth

· iOS 6: Core Bluetooth advertising· iOS 7: Multipeer Connectivity &

iBeacons· iOS 8: Handoff

Page 11: Synchronizing without internet - Multipeer Connectivity (iOS)

Changelog· iOS 3: Game Kit

· iOS 4: Game Center· iOS 5: Core Bluetooth

· iOS 6: Core Bluetooth advertising· iOS 7: Multipeer Connectivity &

iBeacons· iOS 8: Handoff

Page 12: Synchronizing without internet - Multipeer Connectivity (iOS)

MultipeerConnectivity

Page 13: Synchronizing without internet - Multipeer Connectivity (iOS)

Multipeer connectivity· Appears in iOS7.

· Ability to connect to a mesh of peers.· Able to connect to peers over WiFi, ad-

hoc wireless, and Bluetooth.· Doesn't require server infraestructure.

· Peers must be 'nearby'.

Page 14: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 15: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 16: Synchronizing without internet - Multipeer Connectivity (iOS)

MultipeerConnectivity.frameworkBonjour | CFNetwork

Page 17: Synchronizing without internet - Multipeer Connectivity (iOS)

Two phases· Discovery· Session

Page 18: Synchronizing without internet - Multipeer Connectivity (iOS)

Classes#import <MultipeerConnectivity/MultipeerConnectivity.h>

Session infoDiscovery

Advertisement

Page 19: Synchronizing without internet - Multipeer Connectivity (iOS)

Session info· MCPeerId· MCSession

Page 20: Synchronizing without internet - Multipeer Connectivity (iOS)

MCPeerIdMCPeerID *peerId = [[MCPeerID alloc] initWithDisplayName:self.deviceName];

Page 21: Synchronizing without internet - Multipeer Connectivity (iOS)

MCSessionMCSession *session = [[MCSession alloc] initWithPeer:self.peerId];

session.delegate = self;

Page 22: Synchronizing without internet - Multipeer Connectivity (iOS)

<MCSessionDelegate>- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state{ switch (state): { case MCSessionStateConnected: ... case MCSessionStateConnecting: ... case MCSessionStateNotConnected: ... }}

Page 23: Synchronizing without internet - Multipeer Connectivity (iOS)

<MCSessionDelegate>// DATA- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {}

// RESOURCES- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress {}- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error{}

// STREAMS- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID{}

Page 24: Synchronizing without internet - Multipeer Connectivity (iOS)

Discovery· MCBrowserViewController· MCNearbyServiceBrowser

Page 25: Synchronizing without internet - Multipeer Connectivity (iOS)

MCBrowserViewControllerNSString * const serviceIdentifier = @"codemotion-demo";

MCBrowserViewController *browser = [[MCBrowserViewController alloc] initWithServiceType:serviceIdentifier session:self.appdelegate.session];

browser.delegate = self;

[self presentViewController:browser animated:YES completion:nil];

Page 26: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 27: Synchronizing without internet - Multipeer Connectivity (iOS)

<MCBrowserViewControllerDelegate>- (void)browserViewControllerDidFinish:(MCBrowserViewController *)b {}

- (void)browserViewControllerWasCancelled:(MCBrowserViewController *)b {}

Page 28: Synchronizing without internet - Multipeer Connectivity (iOS)

Advertisement· MCAdvertiserAssistant

· MCNearbyServicesAdvertiser

Page 29: Synchronizing without internet - Multipeer Connectivity (iOS)

MCAdvertiserAssistantNSString * const serviceIdentifier = @"codemotion-demo";

MCAdvertiserAssistant *advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:self.serviceIdentifier discoveryInfo:nil session:session];

[advertiser start];

Page 30: Synchronizing without internet - Multipeer Connectivity (iOS)

Session phase

Page 31: Synchronizing without internet - Multipeer Connectivity (iOS)

Sending data· NSData to an array of peers.

· NSURL resource to a peer.· NSStream to a peer.

Page 32: Synchronizing without internet - Multipeer Connectivity (iOS)

Send NSData to an array of peers- (BOOL)sendData:(NSData *)data toPeers:(NSArray *)peerIDs withMode:(MCSessionSendDataMode)mode error:(NSError **)error;

Modes· MCSessionSendDataReliable· MCSessionSendDataUnreliable

Page 33: Synchronizing without internet - Multipeer Connectivity (iOS)

DEMOHello world in MC

Page 34: Synchronizing without internet - Multipeer Connectivity (iOS)

Video

Page 35: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 36: Synchronizing without internet - Multipeer Connectivity (iOS)

Send resource to a peer

- (NSProgress *)sendResourceAtURL:(NSURL *)resourceURL withName:(NSString *)resourceName toPeer:(MCPeerID *)peerID withCompletionHandler:(void(^)(NSError *error))completionHandler;

Page 37: Synchronizing without internet - Multipeer Connectivity (iOS)

ExampleShare images from photo

library

Page 38: Synchronizing without internet - Multipeer Connectivity (iOS)

@property (weak, nonatomic) IBOutlet UIImageView *picture;

Page 39: Synchronizing without internet - Multipeer Connectivity (iOS)

- (IBAction)choosePhoto:(UIButton *)sender{ UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.allowsEditing = NO; picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; picker.mediaTypes = @[(NSString *)kUTTypeImage];

[self presentViewController:picker animated:YES completion:nil];}

Page 40: Synchronizing without internet - Multipeer Connectivity (iOS)

<UIImagePickerDelegate>#pragma mark - UIImagePickerDelegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ UIImage *selectedImage = info[UIImagePickerControllerOriginalImage]; NSData *jpegImg = UIImageJPEGRepresentation(selectedImage, 0.5);

NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingString:@"pic.jpg"]; self.imageURL = [NSURL fileURLWithPath:tmpPath];

[jpegImg writeToURL:self.imageURL atomically:NO];

self.picture.image = selectedImage; [picker dismissViewControllerAnimated:YES completion:nil];}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [picker dismissViewControllerAnimated:YES completion:NULL];}

Page 41: Synchronizing without internet - Multipeer Connectivity (iOS)

<MCSessionDelegate>#pragma mark - - (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress{ dispatch_async(dispatch_get_main_queue(), ^{ self.picture.image = nil; self.picture.backgroundColor = [UIColor yellowColor]; });}

- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error{ NSData *data = [NSData dataWithContentsOfURL:localURL]; UIImage *image = [[UIImage alloc] initWithData:data];

dispatch_async(dispatch_get_main_queue(), ^{ self.picture.image = image; });}

Page 42: Synchronizing without internet - Multipeer Connectivity (iOS)

VideoShare images from photo

library

Page 43: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 44: Synchronizing without internet - Multipeer Connectivity (iOS)

Streaming- (NSOutputStream *)startStreamWithName:(NSString *)streamName toPeer:(MCPeerID *)peerID error:(NSError **)error;

Page 45: Synchronizing without internet - Multipeer Connectivity (iOS)

NSOutputStream: open

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state{ ... if (state == MCSessionStateConnected) { NSError *error; NSOutputStream *output = [session startStreamWithName:@"streamName" toPeer:peer error:&error];

if (error) { return; }

[output scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [output open]; } ...}

Page 46: Synchronizing without internet - Multipeer Connectivity (iOS)

NSOutputStream: write

NSData *data = [NSData data]; [self.output write:data.bytes maxLength:data.length];

Page 47: Synchronizing without internet - Multipeer Connectivity (iOS)

NSInputStream- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID{ stream.delegate = self; [stream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [stream open];}

Page 48: Synchronizing without internet - Multipeer Connectivity (iOS)

<NSStreamDelegate>- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{ switch (eventCode) { case NSStreamEventOpenCompleted: ... case NSStreamEventEndEncountered: ... case NSStreamEventHasBytesAvailable: { NSInputStream *inputStream = (NSInputStream *)aStream;

uint8_t buffer[1024]; NSInteger size = [inputStream read:(uint8_t *)buffer maxLength:1024];

NSData *data = [NSData dataWithBytes:buffer length:size]; ... // Manage data received ... break; } default: break; }}

Page 49: Synchronizing without internet - Multipeer Connectivity (iOS)

ExampleShared whiteboard

Page 50: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 51: Synchronizing without internet - Multipeer Connectivity (iOS)

UIPanGestureRecognizer- (IBAction)panReceived:(UIPanGestureRecognizer *)sender{ CGPoint point = [sender locationInView:sender.view];

[self.drawable drawPoint:point state:sender.state];

NSData *data = [NSData drawDataWithGestureState:sender.state point:[sender locationInView:sender.view]]; [self.output write:data.bytes maxLength:data.length];}

Page 52: Synchronizing without internet - Multipeer Connectivity (iOS)

- (void)drawPoint:(CGPoint)point state:(UIGestureRecognizerState)state{ switch (state) { case UIGestureRecognizerStateBegan: { lastPoint = point; break; } case UIGestureRecognizerStateChanged: { CGPoint currentPoint = point;

UIGraphicsBeginImageContext(self.layout.frame.size); [self.tmpLayout.image drawInRect:CGRectMake(0, 0, self.layout.frame.size.width, self.layout.frame.size.height)]; CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 10); CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 0, 0, 1.0); CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);

CGContextStrokePath(UIGraphicsGetCurrentContext()); self.tmpLayout.image = UIGraphicsGetImageFromCurrentImageContext(); [self.tmpLayout setAlpha:1]; UIGraphicsEndImageContext();

lastPoint = currentPoint; break; } case UIGestureRecognizerStateEnded: { UIGraphicsBeginImageContext(self.layout.frame.size); [self.layout.image drawInRect:CGRectMake(0, 0, self.layout.frame.size.width, self.layout.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0]; [self.tmpLayout.image drawInRect:CGRectMake(0, 0, self.layout.frame.size.width, self.layout.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0]; self.layout.image = UIGraphicsGetImageFromCurrentImageContext(); self.tmpLayout.image = nil; UIGraphicsEndImageContext(); break; }

default: break; }}

Page 53: Synchronizing without internet - Multipeer Connectivity (iOS)

- (void)clearScreen{ UIGraphicsBeginImageContext(self.layout.frame.size); CGContextRef ctx = UIGraphicsGetCurrentContext();

CGContextSetRGBFillColor(ctx, 255.0, 255.0, 255.0, 1.0); CGContextFillRect(ctx, CGRectMake(0, 0, self.tmpLayout.frame.size.width, self.tmpLayout.frame.size.height)); self.layout.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();}

Page 54: Synchronizing without internet - Multipeer Connectivity (iOS)

VideoShared whiteboard

Page 55: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 56: Synchronizing without internet - Multipeer Connectivity (iOS)

All together

Page 57: Synchronizing without internet - Multipeer Connectivity (iOS)

'simple sync' example· n-devices.

· Create a hash by each register based in time.

· First sync in batch using a file.· NSOutputstream to send 'ligth data'.

· Off and on send counters & timers using MCSessionSendDataReliable.

Page 58: Synchronizing without internet - Multipeer Connectivity (iOS)

'simple sync' example· n-devices.

· Create a hash by each register based in time.

· First sync in batch using a file.· NSOutputstream to send 'ligth data'.

· Off and on send counters & timers using MCSessionSendDataReliable.

Page 59: Synchronizing without internet - Multipeer Connectivity (iOS)
Page 60: Synchronizing without internet - Multipeer Connectivity (iOS)

Ensembles1

"Sync for Core Data Apps"1 http://www.ensembles.io

Page 61: Synchronizing without internet - Multipeer Connectivity (iOS)

How far can I ...

Page 62: Synchronizing without internet - Multipeer Connectivity (iOS)

How far can I ...

- RADIOUS2.

- DevRocket3

...

3 DeckRocket: https://github.com/jpsim/DeckRocket.

2 RADIOUS: https://itunes.apple.com/nz/app/radious-walkie-talkie/id738480541?mt=8.

Page 63: Synchronizing without internet - Multipeer Connectivity (iOS)

Questions?

Page 64: Synchronizing without internet - Multipeer Connectivity (iOS)

Thanks@patoroco


Top Related