`
haoningabc
  • 浏览: 1482775 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ios仿微信的demo

    博客分类:
  • ios
ios 
阅读更多

10月19日闲的蛋疼,做了个
仿微信的聊天工具
git地址:https://github.com/killinux/mysocket/tree/master/websocket/project/Test
ui参考的网上例子http://ios.9tech.cn/news/2013/1111/38520.html
服务端用 tomcat7的websocket
客户端
1.可以用浏览器
2.sockroket的ios客户端,ios8,开发工具xcode6
ios客户端代码如下代码:
ViewController.m
//
//  ViewController.m
//  BubbleDemo
//
//  Created by xiao7 on 14/10/19.
//  Copyright (c) 2014年 killinux. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

NSString *websocket_url = @"ws://192.168.0.102:8080/webs/websocket/test";
NSString *myName = @"haoning";
NSString *toName = @"all";
- (void)viewDidLoad {
    [super viewDidLoad];
//----init data---begin----
//    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"weixin",@"name",@"这是一个测试",@"content", nil];
//    NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"haoning",@"name",@"hello",@"content", nil];
//    NSDictionary *dict7 = [NSDictionary dictionaryWithObjectsAndKeys:@"weixin",@"name",@",长数据测试。",@"content", nil];
//    _resultArray = [NSMutableArray arrayWithObjects:dict,dict1, nil];
//    [_resultArray addObject:dict7];
    
    _resultArray = [[NSMutableArray alloc] init];
//----init data---end----
//websocket---begin---
    _mywebSocket.delegate = nil;
    [_mywebSocket close];
    _mywebSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:websocket_url]]];
    _mywebSocket.delegate = self;
    [_mywebSocket open];
    NSLog(@"open success!");
//websocket---end----
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
//pragma websocket
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
{
    NSLog(@"Websocket Connected");
    self.title = @"Connected!";
}

- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
{
    NSLog(@":( Websocket Failed With Error %@", error);
    _mywebSocket = nil;
}

- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
{
    NSLog(@"websocket Received \"%@\"", message);
    NSArray *messageArray = [message componentsSeparatedByString:@","];
    if(messageArray.count<3){
        NSLog(@"error parameter not right:%@",message);
//        NSDictionary *dict8 = [NSDictionary dictionaryWithObjectsAndKeys:@"haoning",@"name",message,@"content", nil];
//        [_resultArray addObject:dict8];
    }else{
        NSDictionary *dict8 = [NSDictionary dictionaryWithObjectsAndKeys:messageArray[0],@"name",messageArray[2],@"content", nil];
        [_resultArray addObject:dict8];
    }
    [tableViewList reloadData];
}

- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
{
    NSLog(@"WebSocket closed");
    self.title = @"Connection Closed! (see logs)";
    _mywebSocket = nil;
}
//发送消息
- (IBAction)sendBubbleMessage:(id)sender {
    NSString *thistext = messageTxt.text;
    NSLog(@"sendBubbleMessage:%@",thistext);
//    NSDictionary *dict8 = [NSDictionary dictionaryWithObjectsAndKeys:@"haoning",@"name",thistext,@"content", nil];
//    [_resultArray addObject:dict8];
//    [tableViewList reloadData];
    NSString *sendMessage =[myName stringByAppendingFormat:@",%@,%@",toName,thistext];
    [_mywebSocket send:sendMessage];
    messageTxt.text=nil;
}

//泡泡文本
- (UIView *)bubbleView:(NSString *)text from:(BOOL)fromSelf withPosition:(int)position{
    
    //计算大小
    UIFont *font = [UIFont systemFontOfSize:14];
    CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(180.0f, 20000.0f) lineBreakMode:NSLineBreakByWordWrapping];
    
    // build single chat bubble cell with given text
    UIView *returnView = [[UIView alloc] initWithFrame:CGRectZero];
    returnView.backgroundColor = [UIColor clearColor];
    
    //背影图片
    UIImage *bubble = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fromSelf?@"SenderAppNodeBkg_HL":@"ReceiverTextNodeBkg" ofType:@"png"]];
    
    UIImageView *bubbleImageView = [[UIImageView alloc] initWithImage:[bubble stretchableImageWithLeftCapWidth:floorf(bubble.size.width/2) topCapHeight:floorf(bubble.size.height/2)]];
    //NSLog(@"%f,%f",size.width,size.height);
    UILabel *bubbleText = [[UILabel alloc] initWithFrame:CGRectMake(fromSelf?15.0f:22.0f, 20.0f, size.width+10, size.height+10)];
    bubbleText.backgroundColor = [UIColor clearColor];
    bubbleText.font = font;
    bubbleText.numberOfLines = 0;
    bubbleText.lineBreakMode = NSLineBreakByWordWrapping;
    bubbleText.text = text;
    bubbleImageView.frame = CGRectMake(0.0f, 14.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+20.0f);
    if(fromSelf)
        returnView.frame = CGRectMake(320-position-(bubbleText.frame.size.width+30.0f), 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f);
    else
        returnView.frame = CGRectMake(position, 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f);
    
    [returnView addSubview:bubbleImageView];
    [returnView addSubview:bubbleText];
    
    return returnView;
}

//泡泡语音
- (UIView *)yuyinView:(NSInteger)logntime from:(BOOL)fromSelf withIndexRow:(NSInteger)indexRow  withPosition:(int)position{
    
    //根据语音长度
    int yuyinwidth = 66+fromSelf;
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.tag = indexRow;
    if(fromSelf)
        button.frame =CGRectMake(320-position-yuyinwidth, 10, yuyinwidth, 54);
    else
        button.frame =CGRectMake(position, 10, yuyinwidth, 54);
    
    //image偏移量
    UIEdgeInsets imageInsert;
    imageInsert.top = -10;
    imageInsert.left = fromSelf?button.frame.size.width/3:-button.frame.size.width/3;
    button.imageEdgeInsets = imageInsert;
    
    [button setImage:[UIImage imageNamed:fromSelf?@"SenderVoiceNodePlaying":@"ReceiverVoiceNodePlaying"] forState:UIControlStateNormal];
    UIImage *backgroundImage = [UIImage imageNamed:fromSelf?@"SenderVoiceNodeDownloading":@"ReceiverVoiceNodeDownloading"];
    backgroundImage = [backgroundImage stretchableImageWithLeftCapWidth:20 topCapHeight:0];
    [button setBackgroundImage:backgroundImage forState:UIControlStateNormal];
    
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(fromSelf?-30:button.frame.size.width, 0, 30, button.frame.size.height)];
    label.text = [NSString stringWithFormat:@"%d''",logntime];
    label.textColor = [UIColor grayColor];
    label.font = [UIFont systemFontOfSize:13];
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor clearColor];
    [button addSubview:label];
    
    return button;
}

#pragma UITableView

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _resultArray.count;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *dict = [_resultArray objectAtIndex:indexPath.row];
    UIFont *font = [UIFont systemFontOfSize:14];
    CGSize size = [[dict objectForKey:@"content"] sizeWithFont:font constrainedToSize:CGSizeMake(180.0f, 20000.0f) lineBreakMode:NSLineBreakByWordWrapping];
    
    return size.height+44;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }else{
        for (UIView *cellView in cell.subviews){
            [cellView removeFromSuperview];
        }
    }
    NSDictionary *dict = [_resultArray objectAtIndex:indexPath.row];
    
    //创建头像
    UIImageView *photo ;
    if ([[dict objectForKey:@"name"]isEqualToString:@"haoning"]) {
        photo = [[UIImageView alloc]initWithFrame:CGRectMake(320-60, 10, 50, 50)];
        [cell addSubview:photo];
        photo.image = [UIImage imageNamed:@"photo1"];
        
        if ([[dict objectForKey:@"content"] isEqualToString:@"0"]) {
            [cell addSubview:[self yuyinView:1 from:YES withIndexRow:indexPath.row withPosition:65]];
            
        }else{
            [cell addSubview:[self bubbleView:[dict objectForKey:@"content"] from:YES withPosition:65]];
        }
        
    }else{
        photo = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 50, 50)];
        [cell addSubview:photo];
        photo.image = [UIImage imageNamed:@"photo"];
        
        if ([[dict objectForKey:@"content"] isEqualToString:@"0"]) {
            [cell addSubview:[self yuyinView:1 from:NO withIndexRow:indexPath.row withPosition:65]];
        }else{
            [cell addSubview:[self bubbleView:[dict objectForKey:@"content"] from:NO withPosition:65]];
        }
    }
    
    return cell;
    
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
}

@end



ViewController.h
//
//  ViewController.h
//  BubbleDemo
//
//  Created by xiao7 on 14/10/19.
//  Copyright (c) 2014年 killinux. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "SocketRocket/SRWebSocket.h"
@interface ViewController : UIViewController<SRWebSocketDelegate>
{

    IBOutlet UITableView *tableViewList;
    IBOutlet UITextField *messageTxt;
    
}
@property (nonatomic, strong) NSMutableArray *resultArray;
@property (nonatomic, strong) SRWebSocket *mywebSocket;
@end


演示
chrome上

ios8系统上


html的客户端
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<script type="text/javascript">
	String.prototype.startWith=function(s){
	  if(s==null||s==""||this.length==0||s.length>this.length)
	   return false;
	  if(this.substr(0,s.length)==s)
	     return true;
	  else
	     return false;
	  return true;
	 }
	Date.prototype.format = function(format) {
		var o = {
			"M+" : this.getMonth() + 1, //month
			"d+" : this.getDate(), //day
			"h+" : this.getHours(), //hour
			"m+" : this.getMinutes(), //minute
			"s+" : this.getSeconds(), //second
			"q+" : Math.floor((this.getMonth() + 3) / 3), //quarter
			"S" : this.getMilliseconds()
		}
		if (/(y+)/.test(format))
			format = format.replace(RegExp.$1, (this.getFullYear() + "")
					.substr(4 - RegExp.$1.length));
		for ( var k in o)
			if (new RegExp("(" + k + ")").test(format))
				format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k]
						: ("00" + o[k]).substr(("" + o[k]).length));
		return format;
	}
	var ws = null;
	function log(text) {
		/* document.getElementById("log").innerHTML = (new Date).getTime() + ": "
				+ text + "<br>" + document.getElementById("log").innerHTML; */
		document.getElementById("log").innerHTML = new Date().format('yyyy-MM-dd hh:mm:ss') + ","
		+ text + "<br>" + document.getElementById("log").innerHTML;
	}
	function enterSend(){
		if(event.keyCode == 13){
		    document.getElementById("sendbtn").click();
		}
	}
	function startServer() {
		
		var url = document.getElementById("serverip").value;// "ws://192.168.0.102:8887";  
		if ('WebSocket' in window) {
			ws = new WebSocket(url);
		} else if ('MozWebSocket' in window) {
			ws = new MozWebSocket(url);
		} else {
			log('浏览器不支持');
			return;
		}
		ws.onopen = function() {
			log('唷嘻,连上了');
		};
		// 收到服务器发送的文本消息, event.data表示文本内容  
		ws.onmessage = function(event) {
			var thisdata = event.data;
			if(thisdata.startWith("open")){
				//alert(thisdata);
				document.getElementById("username").value=thisdata.split(" ")[1];
			}else{
				//log(event.data);
				var showData=event.data.split(",");
				log(showData[0]+"说:"+showData[2]);
			}
		};
		ws.onclose = function() {
			log('Closed! 刷新页面尝试连接.');
		}
		//document.getElementById("conbtn").disabled = "true";
		//document.getElementById("stopbtn").removeAttribute('disabled');
	}
	function sendMessage() {
		var textMessage = document.getElementById("textMessage").value;
		var username = document.getElementById("username").value;
		var toUser = "";
		if (ws != null && textMessage != "") {
			ws.send(username+","+toUser+","+textMessage);
		}
		document.getElementById("textMessage").value="";
	}
	function stopconn() {
		ws.close();
		//document.getElementById("conbtn").removeAttribute('disabled');
		//document.getElementById("stopbtn").disabled = "true";
	}
</script>
<body onload="startServer()">

	 <input id="serverip" type="text" size="20"
		value="ws://192.168.0.102:8080/webs/websocket/test" /> 
	<!-- ws://192.168.0.102:8887 182.254.155.153 -->
	<!-- <input id="conbtn" type="button" onclick="startServer()" value="open" />
		<input id="stopbtn" type="button" onclick="stopconn()" value="stop" disabled="disabled"/> -->
	</br>
	您的名字:<input id="username" type="text"  /></br></br>
	<input id="textMessage" type="text" size="20" onkeydown="enterSend()"  style="border:1;width:400px"  />
	<input id="sendbtn" type="button" onclick="sendMessage()" value="Send">
	<div id="log"></div>
</body>
</html>



java的tomcat7的后台:
package com.hao;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;

public class HelloWorldWebSocketServlet extends WebSocketServlet {
	public static Map<String,MyMessageInbound> mmiList  = new HashMap<String,MyMessageInbound>();

	protected StreamInbound createWebSocketInbound(String subProtocol,
			HttpServletRequest arg1) {
		return new MyMessageInbound();
	}
	public int getUserCount(){
		return mmiList.size();
	}
	private class MyMessageInbound extends MessageInbound {
		WsOutbound myoutbound;
		String mykey;
		@Override
		public void onOpen(WsOutbound outbound) {
			try {
				System.out.println("Open Client.");
				this.myoutbound = outbound;
				mykey ="open "+System.currentTimeMillis();;
				mmiList.put(mykey, this);
				System.out.println("mmiList size:"+mmiList.size());
				outbound.writeTextMessage(CharBuffer.wrap(mykey));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onClose(int status) {
			System.out.println("Close Client.");
			//mmiList.remove(this);
			mmiList.remove(mykey);
		}

		@Override
		protected void onBinaryMessage(ByteBuffer arg0) throws IOException {

		}

		@Override
		protected void onTextMessage(CharBuffer message) throws IOException {
			// TODO Auto-generated method stub
			System.out.println("onText--->" + message.toString());
//			for (int i=0;i< mmiList.size();i++ ) {
//				MyMessageInbound mmib = (MyMessageInbound) mmiList.get(i);
//                CharBuffer buffer = CharBuffer.wrap(message);
//                mmib.myoutbound.writeTextMessage(buffer);
//                mmib.myoutbound.flush();
//            }
			for (Map.Entry<String, MyMessageInbound> entry : mmiList.entrySet()) {
				  //System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
				  MyMessageInbound mmib = (MyMessageInbound) entry.getValue();
				 // String str = entry.getKey()+message.toString()
	              CharBuffer buffer = CharBuffer.wrap(message);
	              mmib.myoutbound.writeTextMessage(buffer);
	              mmib.myoutbound.flush();
			}
			
			/*Socket socket;
			String msg = "";
			try {
				// 向服务器利用Socket发送信息
				socket = new Socket("192.168.0.102", 5000);
				// socket = new Socket("127.0.0.1",5000);
				PrintWriter output = new PrintWriter(socket.getOutputStream());

				output.write(message.toString());
				output.flush();

				// 这里是接收到Server的信息
				DataInputStream input = new DataInputStream(
						socket.getInputStream());
				byte[] b = new byte[1024];
				input.read(b);
				// Server返回的信息
				msg = new String(b).trim();

				output.close();
				input.close();
				socket.close();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			// 往浏览器发送信息
			CharBuffer cb = CharBuffer.wrap(new StringBuilder(msg));
			getWsOutbound().writeTextMessage(cb);*/
		}
	}

	public static void main(String[] args) {
		Socket socket;
		String message = "haoning";
		String msg = "";
		try {
			// 向服务器利用Socket发送信息
			socket = new Socket("192.168.0.102", 5000);
			// socket = new Socket("127.0.0.1",5000);
			PrintWriter output = new PrintWriter(socket.getOutputStream());

			output.write(message.toString());
			output.flush();

			// 这里是接收到Server的信息
			DataInputStream input = new DataInputStream(socket.getInputStream());
			byte[] b = new byte[1024];
			input.read(b);
			// Server返回的信息
			msg = new String(b).trim();

			output.close();
			input.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


web.xml
   <servlet>
      <servlet-name>wsSnake</servlet-name>
      <servlet-class>com.hao.HelloWorldWebSocketServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>wsSnake</servlet-name>
      <url-pattern>/websocket/test</url-pattern>
    </servlet-mapping>
  • 大小: 260.1 KB
  • 大小: 39 KB
  • 大小: 80 KB
分享到:
评论

相关推荐

    ios-高仿微信通讯录.zip

    在iOS开发中,高仿微信通讯录是一项挑战性的工作,涉及到UI设计、数据管理、手势识别等多个技术领域。本项目“ios-高仿微信通讯录.zip”旨在复刻微信通讯录的功能,包括联系人搜索、分组滑动以及交互效果。下面将...

    ios+dome+仿微信+主界面+部分代码

    在iOS开发中,仿微信主界面是一项常见的学习任务,它能帮助开发者理解并掌握iOS应用设计的基本原则,以及如何利用Swift或Objective-C编程语言来实现类似功能。"ios+dome+仿微信+主界面+部分代码"这个项目,提供了一...

    iOS 微信支付demo

    "iOS微信支付demo"是一个示例项目,它展示了如何在iOS应用中集成微信支付SDK,以便用户能够方便快捷地进行在线交易。这里我们将详细讲解相关的技术知识。 1. **微信开放平台注册** 首先,开发者需要在[微信开放...

    IOS 微信支付Demo

    【iOS微信支付Demo】是一个专为iOS开发者设计的示例项目,它展示了如何在iOS应用中集成微信支付功能。这个项目使用了CocoaPods这一流行的依赖管理工具,以简化第三方库的引入和管理。在着手使用这个Demo之前,你需要...

    IOS高仿微信聊天对话界面(二)

    模仿微信聊天界面,实现的气泡对话,效果瞒不错的,自己整理的,希望正在做这一块儿的同学没头绪的做个参考。 这个是 http://download.csdn.net/download/rhljiayou/6524347 此Demo的升级版,有问题修改

    仿微信demo+

    【标题】"仿微信demo+" 是一个针对移动设备开发的应用程序示例,旨在模拟微信的主要功能和用户体验。这个项目可能是为了教学目的或者开发者自我提升,通过实现类似微信的交互和特性,来熟悉移动应用开发流程。 ...

    iOS_ 微信支付demo

    这个“iOS_微信支付demo”是为开发者提供的一份实例代码,旨在帮助他们理解和实现微信支付功能。下面将详细介绍微信支付的参数、支付流程以及相关注意事项。 一、微信支付参数说明 1. `appID`:应用的唯一标识,由...

    仿微信二维码扫描SYQRCodeDemo.zip

    仿微信二维码扫描,IOS原生API,需要IOS7.0及以上系统支持。简单易用,使用block做回调处理。  SYQRCode:仿微信二维码扫描 Latest 修复bug,优化实现和用户体验,更加简单易用(新增类似微信...

    ios-仿微信选择多张图片上传.zip

    这是一个仿微信的多图片上传,也可以进行图片浏览。不过,该demo还是存在很多需要改进的地方,比如浏览图片不清晰情况。希望各位知道如何解决的可以指出来~~或者可以加我QQ:529074865,大家相互讨论学习~~

    ios-仿微信添加银行卡6位密码输入,弹出层6位密码输入.zip

    这个"ios-仿微信添加银行卡6位密码输入,弹出层6位密码输入.zip"压缩包文件就是一个实例,它展示了如何创建一个用于输入银行信用卡6位密码的弹出视图。下面将详细介绍这一功能的实现原理和相关知识点。 首先,我们...

    完整的仿微信聊天DEMO

    通过分析这个"完整的仿微信聊天DEMO",我们可以学到如何构建一个功能完备的即时通讯应用,包括从底层通信协议到上层用户界面的各个层面。这对于提升移动应用开发技能,特别是即时通讯领域的专业能力大有裨益。

    高仿微信demo

    【高仿微信demo】是一个项目,旨在模仿微信的多种核心功能,为开发者提供一个学习和实践的平台。这个项目不仅涵盖了微信的基本界面设计,还包含了诸如"扫一扫"、"摇一摇"等特色功能的实现,是理解微信应用工作原理和...

    IOS8 微信支付 demo,能成功运行

    这个"微信支付 iOS8 Demo"提供了一个可以成功运行的示例代码,帮助开发者理解和集成微信支付功能到他们的应用程序中。以下是关于iOS 8微信支付的详细知识点: 1. **iOS 8系统特性**:iOS 8是苹果在2014年推出的操作...

    ios-仿微信发动态选择联系人可见.zip

    "ios-仿微信发动态选择联系人可见.zip"这个压缩包文件显然包含了一个示例项目,目的是帮助开发者理解并实现类似微信动态发布时选择可见联系人的功能。在这个过程中,用户可以选择哪些联系人可以看到他们分享的内容,...

    iOS 微信第三方登录 Demo

    iOS 微信第三方登录小Demo,有兴趣可以学习下。

    高仿微信demo,内含截取本地图片,截取手机拍照图片作为头像

    综上所述,"高仿微信demo"的实现涵盖了Android应用开发中的多个关键知识点,包括Intent交互、图片处理、权限管理、UI设计以及用户体验优化。通过这个项目,开发者可以深入理解Android系统的工作原理,同时提升自己的...

    IOS 微信支付官方Demo

    【iOS微信支付官方Demo】是微信为iOS开发者提供的一个示例项目,用于帮助开发者集成微信支付功能。这个Demo包含了从初始化支付流程到处理支付结果的完整步骤,是开发者理解和实践微信支付API的重要参考资料。 首先...

    IOS微信移动应用扫码登录DEMO

    这个"IOS微信移动应用扫码登录DEMO"就是一个典型的示例,它展示了如何在iOS应用中集成微信SDK,实现在应用内部生成二维码,并通过微信客户端扫描进行登录。 首先,我们需要了解的是微信开放平台。微信开放平台提供...

    2015 iOS最新微信支付demo

    这个2015年发布的iOS微信支付demo提供了详细的示例代码,可以帮助开发者快速理解和上手。它可能包括了从生成订单、请求预支付会话标识、构造支付请求到处理回调的完整流程。对于初学者,可以按照demo的步骤逐步调试...

    YFLProgress 仿微信朋友圈删除的HUD

    综上所述,"YFLProgress 仿微信朋友圈删除的HUD" 是一个用于iOS开发的用户界面组件,它模仿了微信应用中的特定加载等待动画。开发者可以通过学习这个组件的实现思路,结合提供的Demo,来为自己的应用添加类似的功能...

Global site tag (gtag.js) - Google Analytics