1. 程式人生 > >iOS scoket 再探。換成了GCDAsyncSocket,並且實現了雙方聊天

iOS scoket 再探。換成了GCDAsyncSocket,並且實現了雙方聊天

學習iOS也有一段時間了。也在試著用iOS來寫專案,感謝各路大神的幫助,就不一一@了。本文只是記載本人的學習過程。

                                                                           ---------------------學如逆水行舟不進則退。

1.這次換成了GCDAsyncSocket框架,先看下完成圖吧


另一方



貼上程式碼吧,有註釋估計不難

客戶

.h

//

//  RootViewController.h

//  hqhtestsocket

//

//  Created by黃權浩 on 14-12-11.

//  Copyright (c) 2014黃權浩. All rights reserved.

//

#import <UIKit/UIKit.h>

#import "GCDAsyncSocket.h"

@interface RootViewController : UIViewController<GCDAsyncSocketDelegate,UITextFieldDelegate>

{

    GCDAsyncSocket *socket;

    //傳送訊息按鈕

    UIButton *sendMg2;

    //傳送訊息

//鍵盤彈起來的通知變化

    UIView *TestV;

    UITextField *textView;

}

@property(strong)  GCDAsyncSocket *socket;

//IP

@property (weak, nonatomic) IBOutlet UITextField *ip;

//

@property (weak, nonatomic) IBOutlet UITextField *duankou;

//連線伺服器

- (IBAction)lianjie:(id)sender;

//展示訊息

@property (weak, nonatomic) IBOutlet UITextView *showMg;

.m

//

//  RootViewController.m

//  hqhtestsocket

//

//  Created by黃權浩 on 14-12-11.

//  Copyright (c) 2014黃權浩. All rights reserved.

//

#import "RootViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController

@synthesize socket;

- (void)viewDidLoad {

    [super viewDidLoad];

//註冊鍵盤通知來讓訊息框彈起

    [self registerForKeyboardNotifications];

//搭建聊天的頁面

    TestV = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height-50, 320, 50)];

    //開啟互動

    TestV.userInteractionEnabled = YES;

    TestV.backgroundColor = [UIColor grayColor];

    //搞個UITextView

    textView = [[UITextField alloc] initWithFrame:CGRectMake(10, 5, 230, 40)];

    textView.delegate = self;

    textView.borderStyle = UITextBorderStyleRoundedRect;

//搞個傳送訊息的按鈕

    UIButton *sendMg = [UIButton buttonWithType:UIButtonTypeCustom];

    [sendMg setTitle:@"Send" forState:UIControlStateNormal];

    [sendMg setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

    [sendMg addTarget:self action:@selector(sendMG) forControlEvents:UIControlEventTouchUpInside];

    [sendMg setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];

    sendMg.frame = CGRectMake(250, 5, 60, 40);

    [TestV addSubview:sendMg];

    [TestV addSubview:textView];

    [self.view addSubview:TestV];

}

//註冊鍵盤彈起來的通知

- (void)registerForKeyboardNotifications

{

    //監聽鍵盤擡起

//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showContentViewPoint:) name:UIKeyboardWillShowNotification object:nil];

    //監聽鍵盤收回

//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hiddenContentViewPoint:) name:UIKeyboardWillShowNotification object:nil];

    //監聽鍵盤改變

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeContentViewPoint:) name:UIKeyboardWillShowNotification object:nil];

}

//鍵盤的通知

- (void)changeContentViewPoint:(NSNotification *)notification{

    NSDictionary *userInfo = [notification userInfo];

    NSValue *value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

    CGFloat keyBoardEndY = value.CGRectValue.origin.y;

// 得到鍵盤彈出後的鍵盤檢視所在y座標

    NSNumber *duration = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];    NSNumber *curve = [userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];

// 新增移動動畫,使檢視跟隨鍵盤移動

    [UIView animateWithDuration:duration.doubleValue animations:^{

        [UIView setAnimationBeginsFromCurrentState:YES];

        [UIView setAnimationCurve:[curve intValue]];

        TestV.center = CGPointMake(TestV.center.x, keyBoardEndY - TestV.bounds.size.height/2.0);

        // keyBoardEndY的座標包括了狀態列的高度,要減去

    }

     ];

}

//收起鍵盤

- (void)dsms{

    [textView resignFirstResponder];

    [_duankou resignFirstResponder];

    [_ip resignFirstResponder];

    //做動畫過渡

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:0.3];

    [UIView setAnimationDelegate:self];

    TestV.frame = CGRectMake(0, self.view.bounds.size.height-50, 320, 50);

    [UIView commitAnimations];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

//將訊息顯示換行

-(void)addText:(NSString *)str

{

    _showMg.text = [_showMg.text stringByAppendingFormat:@"%@\n",str];

}

//連線伺服器

- (IBAction)lianjie:(id)sender {

    socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    //socket.delegate = self;

    NSError *err = nil;

    if(![socket connectToHost:_ip.text onPort:[_duankou.text intValue] error:&err])

    {

        [self addText:err.description];

    }else

    {

        NSLog(@"ok");

        [self addText:@"開啟埠"];

    }

    [self dsms];

}

//連線到的地方

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port

{

    [self addText:[NSString stringWithFormat:@"連線到:%@",host]];

    [socket readDataWithTimeout:-1 tag:0];

}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err

{

}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

{

    NSString *newMessage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    [self addText:[NSString stringWithFormat:@"伺服器:%@:%@",sock.connectedHost,newMessage]];

    [socket readDataWithTimeout:-1 tag:0];

}

//傳送訊息

- (void)sendMG{

    //做動畫過渡

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:0.3];

    [UIView setAnimationDelegate:self];

    TestV.frame = CGRectMake(0, self.view.bounds.size.height-50, 320, 50);

    [UIView commitAnimations];

    [socket writeData:[textView.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];

    [self addText:[NSString stringWithFormat:@":%@",textView.text]];

    [textView resignFirstResponder];

    [socket readDataWithTimeout:-1 tag:0];

}

@end

nib圖:
另一端 .h

//

//  RootViewController.h

//  hqhtestsocket

//

//  Created by黃權浩 on 14-12-11.

//  Copyright (c) 2014黃權浩. All rights reserved.

//

#import <UIKit/UIKit.h>

#import "GCDAsyncSocket.h"

@interface RootViewController : UIViewController<GCDAsyncSocketDelegate,UITextFieldDelegate>

{

    GCDAsyncSocket *socket;

    //傳送訊息按鈕

    UIButton *sendMg2;

    //傳送訊息

//鍵盤彈起來的通知變化

    UIView *TestV;

    UITextField *textView;

}

@property(strong)  GCDAsyncSocket *socket;

//

@property (weak, nonatomic) IBOutlet UITextField *duankou;

//連線伺服器

- (IBAction)lianjie:(id)sender;

//展示訊息

@property (weak, nonatomic) IBOutlet UITextView *showMg;

@end

.m

//

//  RootViewController.m

//  hqhtestsocket

//

//  Created by黃權浩 on 14-12-11.

//  Copyright (c) 2014黃權浩. All rights reserved.

//

#import "RootViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController

@synthesize socket;

- (void)viewDidLoad {

    [super viewDidLoad];

//註冊鍵盤通知來讓訊息框彈起

    [self registerForKeyboardNotifications];

    //預設埠號

    _duankou.text = @"54321";

//搭建聊天的頁面

    TestV = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height-50, 320, 50)];

    //開啟互動

    TestV.userInteractionEnabled = YES;

    TestV.backgroundColor = [UIColor grayColor];

    //搞個UITextView

    textView = [[UITextField alloc] initWithFrame:CGRectMake(10, 5, 230, 40)];

    textView.delegate = self;

    textView.borderStyle = UITextBorderStyleRoundedRect;

//搞個傳送訊息的按鈕

    UIButton *sendMg = [UIButton buttonWithType:UIButtonTypeCustom];

    [sendMg setTitle:@"Send" forState:UIControlStateNormal];

    [sendMg setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

    [sendMg addTarget:self action:@selector(sendMG) forControlEvents:UIControlEventTouchUpInside];

    [sendMg setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];

    sendMg.frame = CGRectMake(250, 5, 60, 40);

    [TestV addSubview:sendMg];

    [TestV addSubview:textView];

    [self.view addSubview:TestV];

}

- (void)socket:(GCDAsyncSocket *)sender didAcceptNewSocket:(GCDAsyncSocket *)newSocket

{

    // The "sender" parameter is the listenSocket we created.

    // The "newSocket" is a new instance of GCDAsyncSocket.

    // It represents the accepted incoming client connection.

    // Do server stuff with newSocket...

    [self addText:[NSString stringWithFormat:@"建立與%@的連線",newSocket.connectedHost]];

    socket = newSocket;

    socket.delegate = self;

    [socket readDataWithTimeout:-1 tag:0];

}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

{

    NSString *receive = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    [self addText:[NSString stringWithFormat:@"%@:%@",sock.connectedHost,receive]];

    NSString *reply = [NSString stringWithFormat:@"收到:%@",receive];

    [socket writeData:[reply dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];

    [socket readDataWithTimeout:-1 tag:0];

}

//註冊鍵盤彈起來的通知

- (void)registerForKeyboardNotifications

{

    //監聽鍵盤擡起

//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showContentViewPoint:) name:UIKeyboardWillShowNotification object:nil];

    //監聽鍵盤收回

//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hiddenContentViewPoint:) name:UIKeyboardWillShowNotification object:nil];

    //監聽鍵盤改變

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeContentViewPoint:) name:UIKeyboardWillShowNotification object:nil];

}

//鍵盤的通知

- (void)changeContentViewPoint:(NSNotification *)notification{

    NSDictionary *userInfo = [notification userInfo];

    NSValue *value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

    CGFloat keyBoardEndY = value.CGRectValue.origin.y;

// 得到鍵盤彈出後的鍵盤檢視所在y座標

    NSNumber *duration = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];    NSNumber *curve = [userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];

// 新增移動動畫,使檢視跟隨鍵盤移動

    [UIView animateWithDuration:duration.doubleValue animations:^{

        [UIView setAnimationBeginsFromCurrentState:YES];

        [UIView setAnimationCurve:[curve intValue]];

        TestV.center = CGPointMake(TestV.center.x, keyBoardEndY - TestV.bounds.size.height/2.0);

        // keyBoardEndY的座標包括了狀態列的高度,要減去

    }

     ];

}

//收起鍵盤

- (void)dsms{

    [textView resignFirstResponder];

    [_duankou resignFirstResponder];

    //做動畫過渡

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:0.3];

    [UIView setAnimationDelegate:self];

    TestV.frame = CGRectMake(0, self.view.bounds.size.height-50, 320, 50);

    [UIView commitAnimations];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

//將訊息顯示換行

-(void)addText:(NSString *)str

{

    _showMg.text = [_showMg.text stringByAppendingFormat:@"%@\n",str];

}

//監聽

- (IBAction)lianjie:(id)sender {

    NSLog(@"listen");

    socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *err = nil;

    if(![socket acceptOnPort:[_duankou.text integerValue] error:&err])

    {

        [self addText:err.description];

    }else

    {

        [self addText:[NSString stringWithFormat:@"開始監聽%d.",_duankou.text.integerValue]];

    }

}

//連線到的地方

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port

{

    [self addText:[NSString stringWithFormat:@"連線到:%@",host]];

    [socket readDataWithTimeout:-1 tag:0];

}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err

{

}

//傳送訊息

- (void)sendMG{

    //做動畫過渡

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:0.3];

    [UIView setAnimationDelegate:self];

    TestV.frame = CGRectMake(0, self.view.bounds.size.height-50, 320, 50);

    [UIView commitAnimations];

    [textView resignFirstResponder];

    [socket writeData:[textView.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];

    [self addText:[NSString stringWithFormat:@":%@",textView.text]];

    [textView resignFirstResponder];

    [socket readDataWithTimeout:-1 tag:0];

}

@end

nib 圖

實現了相互的聊天 --------------------------------------------日日精進   但求無愧-------------------------------------------