This is the 24th day of my participation in the August Gwen Challenge. For details: August Gwen Challenge “juejin.cn/post/698796…”

preface

The process communication schemes are as follows (select according to the specific scenario)

1: value transfer between apps commonly used by Universal Links and URL schemes, commonly seen in sharing and jumping between apps.

Kunnan.blog.csdn.net/article/det…

2: Keychain is used with the system class KeychainItemWrapper. Common in no-login (between company products)

3: UIPasteboard. Taobao link sharing.

4: UIDocumentInteractionController commonly used for file sharing

5: Local socket

If you are not familiar with IPC, you can read this article Inter Process Communication first

Blog.csdn.net/z929118967/…

The pop-up process of logging in to the iTunes Store input box is controlled by itunesstored, processed by Process :SpringBoard, and messages are transmitted between processes in the way of SBUserNotificationAlert.

I. Solution case: Local socket

Local Socket scheme (TCP) is used to create the server and client to achieve the communication effect.

  • Solution based on GCDAsyncSocket

Supports TCP and UDP encapsulation based on CFSocket and GCD


platform :ios, '8.0'
inhibit_all_warnings!

#use_frameworks!
target 'localScoket' do
   pod 'CocoaAsyncSocket'
end

target 'localScoket4client' do
   pod 'CocoaAsyncSocket'
end

Copy the code

1.1 Basic knowledge: Socket communication process

  • CFSocket (pure C)

Apple provides lightweight encapsulation of the underlying BSD Socket.

API: CFSocekt for establishing connections, CFStream for reading and writing data.

  • tcp

  • UDP

  • The TCP three-way handshake establishes a connection

  • TCP’s four timeswaveRelease the connection

  • Wave and then shake (disconnect and then connect)

  • Shake hands then wave (connect then disconnect)

1.2 serverSocket

#import <GCDAsyncSocket.h>

@interface ViewController(a)

{
    GCDAsyncSocket *_serverSocket;
}

@property(strong.nonatomic)NSMutableArray *clientSocket;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    _clientSocket = [NSMutableArray array];
    
    
    // Create the socket on the server side. Note that the delegate has been specified as well as the initialization
    _serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    
    
    
    [selfstartChatServer]; } - (void)startChatServer{
    // Open the listening port
    NSError *err;
    [_serverSocket acceptOnPort:12345 error:&err];
    if(! err) {NSLog(@"Server service started successfully");
    }else{
        NSLog(@"Server service startup failed"); }}#pragmaMark is called when a client has established a connection- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{
    // Sock indicates the socket on the server. The socket on the server only connects to the client, but does not read data. NSLog(@" server socket %p client socket %p",sock,newSocket);
    // Save the socket of the client. If you do not save the socket, the server will automatically disconnect from the client.
    NSLog(@"Server %s",__func__);
    [self.clientSocket addObject:newSocket];
    
    //newSocket indicates the Socket of the client. This is reading the data
    [newSocket readDataWithTimeout:- 1 tag:100];
}
#pragmaMark server writes data to client- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
    NSLog(@"Server %s",__func__);
    [sock readDataWithTimeout:- 1 tag:100];
}

#pragmaMark receives data from the client- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    //sock indicates the socket of the client
    NSLog(@"Server client socket %p",sock);
    // Data is received
    NSString *receiverStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Server receiverStr :%@",receiverStr);
    // Remove the carriage return and newline characters, sometimes including these two strings, resulting in the judgment of the quit command is not equal
    receiverStr = [receiverStr stringByReplacingOccurrencesOfString:@"\r" withString:@ ""];
    receiverStr = [receiverStr stringByReplacingOccurrencesOfString:@"\n" withString:@ ""];
    
    // Check whether it is login command or send chat data command. These instructions are custom
    // Login command
    if([receiverStr hasPrefix:@"iam:"]) {// Get the user name
        NSString *user = [receiverStr componentsSeparatedByString:@ ","] [1];
        // Respond to the client's data
        NSString *respStr = [user stringByAppendingString:@"has joined"];
        [sock writeData:[respStr dataUsingEncoding:NSUTF8StringEncoding] withTimeout:- 1 tag:0];
    }
    // Chat command
    if ([receiverStr hasPrefix:@"msg:"]) {
        // Intercepts chat messages
        NSString *msg = [receiverStr componentsSeparatedByString:@ ","] [1];
        [sock writeData:[msg dataUsingEncoding:NSUTF8StringEncoding] withTimeout:- 1 tag:0];
    }
    / / the quit command
    if ([receiverStr isEqualToString:@"quit"]) {
        // Disconnect the connection
        [sock disconnect];
        / / remove the socket
        [self.clientSocket removeObject:sock];
    }
    NSLog(@"Server %s",__func__);
}




Copy the code

1.3 clientSocket

See CSDN for this part of the code, or download the demo

1.4 complete the demo

  • CSDN download demo from https://download.csdn.net/download/u011018979/15137188

see also

  • Tweak project to quickly build CocoaAsyncSocket (build, disconnect, reconnect, heartbeat, common request)

Kunnan.blog.csdn.net/article/det…

The authors The article title The article links
Public account: iOS reverse Real-time communication between processes Kunnan.blog.csdn.net/article/det…