first commit

This commit is contained in:
sanya
2025-09-01 14:20:39 +00:00
committed by ExternPointer
commit 490fc11f6a
4328 changed files with 1796224 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
find_package(Threads REQUIRED)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt)
add_executable(sio_console_demo main.cpp)
target_link_libraries(sio_console_demo sioclient)
target_link_libraries(sio_console_demo Threads::Threads)
target_compile_features(sio_console_demo PRIVATE cxx_std_11)
message(STATUS ${Boost_INCLUDE_DIRS} )
#target_include_directories(sio_console_demo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src" ${Boost_INCLUDE_DIRS} )

View File

@@ -0,0 +1,28 @@
#SioChatDemo setup
This Demo is create with `Visual Studio 2012 Update 4` , It is a simple console app, connect to official [socket.io chatroom example](https://github.com/Automattic/socket.io/tree/master/examples/chat) as a chat client.
You can choose a nickname, send/receive message in the chat room, and see join/left information as well.
##boost for windows
Please download boost package from [boost.org](www.boost.org), and unpack to `boost` folder.
Please make sure there's no redundent folder levels under it (by check if `bootstrap.bat` is directly under `boost` folder).
cd to `boost` folder, and run `bootstrap.bat`
Then run:
```shell
bjam stage --toolset=msvc --with-system --with-date_time --with-random --stagedir="release" link=static runtime-link=shared threading=multi release
bjam stage --toolset=msvc --with-system --with-date_time --with-random --stagedir="debug" link=static runtime-link=shared threading=multi debug
```
After done this, use Visual studio command line tool, go to `boost\release` folder, run
```shell
lib.exe /OUT:boost.lib *
```
And do then same thing in `boost\debug` folder.
then you can open the VS project `SioChatDemo.sln` to build and run.
##Visual studio version
Microsoft start to support c++11 after `Visual studio 2012 Update 4`. Please make sure you're using up-to-date version.

View File

@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SioChatDemo", "SioChatDemo.vcxproj", "{3503FCEB-2C8E-441A-A57C-B9DEE9171CF4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3503FCEB-2C8E-441A-A57C-B9DEE9171CF4}.Debug|Win32.ActiveCfg = Debug|Win32
{3503FCEB-2C8E-441A-A57C-B9DEE9171CF4}.Debug|Win32.Build.0 = Debug|Win32
{3503FCEB-2C8E-441A-A57C-B9DEE9171CF4}.Release|Win32.ActiveCfg = Release|Win32
{3503FCEB-2C8E-441A-A57C-B9DEE9171CF4}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3503FCEB-2C8E-441A-A57C-B9DEE9171CF4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SioChatDemo</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>D:\BoostRoot\include\boost-1_55;$(SolutionDir)..\..\..\lib\websocketpp;$(SolutionDir)..\..\..\lib\rapidjson\include;$(IncludePath)</IncludePath>
<LibraryPath>D:\boost_1_55_0\boost_build\debug\lib;$(SolutionDir)boost\$(Configuration)\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)boost;$(SolutionDir)..\..\..\lib\websocketpp;$(SolutionDir)..\..\..\lib\rapidjson\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)boost\$(Configuration)\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>boost.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>boost.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\internal\sio_client_impl.h" />
<ClInclude Include="..\..\..\src\internal\sio_packet.h" />
<ClInclude Include="..\..\..\src\sio_client.h" />
<ClInclude Include="..\..\..\src\sio_message.h" />
<ClInclude Include="..\..\..\src\sio_socket.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\internal\sio_client_impl.cpp" />
<ClCompile Include="..\..\..\src\internal\sio_packet.cpp" />
<ClCompile Include="..\..\..\src\sio_client.cpp" />
<ClCompile Include="..\..\..\src\sio_socket.cpp" />
<ClCompile Include="..\main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,188 @@
//
// sio_test_sample.cpp
//
// Created by Melo Yao on 3/24/15.
//
#include "../../src/sio_client.h"
#include <functional>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <string>
#ifdef WIN32
#define HIGHLIGHT(__O__) std::cout<<__O__<<std::endl
#define EM(__O__) std::cout<<__O__<<std::endl
#include <stdio.h>
#include <tchar.h>
#define MAIN_FUNC int _tmain(int argc, _TCHAR* argv[])
#else
#define HIGHLIGHT(__O__) std::cout<<"\e[1;31m"<<__O__<<"\e[0m"<<std::endl
#define EM(__O__) std::cout<<"\e[1;30;1m"<<__O__<<"\e[0m"<<std::endl
#define MAIN_FUNC int main(int argc ,const char* args[])
#endif
using namespace sio;
using namespace std;
std::mutex _lock;
std::condition_variable_any _cond;
bool connect_finish = false;
class connection_listener
{
sio::client &handler;
public:
connection_listener(sio::client& h):
handler(h)
{
}
void on_connected()
{
_lock.lock();
_cond.notify_all();
connect_finish = true;
_lock.unlock();
}
void on_close(client::close_reason const& reason)
{
std::cout<<"sio closed "<<std::endl;
exit(0);
}
void on_fail()
{
std::cout<<"sio failed "<<std::endl;
exit(0);
}
};
int participants = -1;
socket::ptr current_socket;
void bind_events()
{
current_socket->on("new message", sio::socket::event_listener_aux([&](string const& name, message::ptr const& data, bool isAck,message::list &ack_resp)
{
_lock.lock();
string user = data->get_map()["username"]->get_string();
string message = data->get_map()["message"]->get_string();
EM(user<<":"<<message);
_lock.unlock();
}));
current_socket->on("user joined",sio::socket::event_listener_aux([&](string const& name, message::ptr const& data, bool isAck,message::list &ack_resp)
{
_lock.lock();
string user = data->get_map()["username"]->get_string();
participants = data->get_map()["numUsers"]->get_int();
bool plural = participants !=1;
// abc "
HIGHLIGHT(user<<" joined"<<"\nthere"<<(plural?" are ":"'s ")<< participants<<(plural?" participants":" participant"));
_lock.unlock();
}));
current_socket->on("user left", sio::socket::event_listener_aux([&](string const& name, message::ptr const& data, bool isAck,message::list &ack_resp)
{
_lock.lock();
string user = data->get_map()["username"]->get_string();
participants = data->get_map()["numUsers"]->get_int();
bool plural = participants !=1;
HIGHLIGHT(user<<" left"<<"\nthere"<<(plural?" are ":"'s ")<< participants<<(plural?" participants":" participant"));
_lock.unlock();
}));
}
MAIN_FUNC
{
sio::client h;
connection_listener l(h);
h.set_open_listener(std::bind(&connection_listener::on_connected, &l));
h.set_close_listener(std::bind(&connection_listener::on_close, &l,std::placeholders::_1));
h.set_fail_listener(std::bind(&connection_listener::on_fail, &l));
h.connect("http://127.0.0.1:3000");
_lock.lock();
if(!connect_finish)
{
_cond.wait(_lock);
}
_lock.unlock();
current_socket = h.socket();
Login:
string nickname;
while (nickname.length() == 0) {
HIGHLIGHT("Type your nickname:");
getline(cin, nickname);
}
current_socket->on("login", sio::socket::event_listener_aux([&](string const& name, message::ptr const& data, bool isAck,message::list &ack_resp){
_lock.lock();
participants = data->get_map()["numUsers"]->get_int();
bool plural = participants !=1;
HIGHLIGHT("Welcome to Socket.IO Chat-\nthere"<<(plural?" are ":"'s ")<< participants<<(plural?" participants":" participant"));
_cond.notify_all();
_lock.unlock();
current_socket->off("login");
}));
current_socket->emit("add user", nickname);
_lock.lock();
if (participants<0) {
_cond.wait(_lock);
}
_lock.unlock();
bind_events();
HIGHLIGHT("Start to chat,commands:\n'$exit' : exit chat\n'$nsp <namespace>' : change namespace");
for (std::string line; std::getline(std::cin, line);) {
if(line.length()>0)
{
if(line == "$exit")
{
break;
}
else if(line.length() > 5&&line.substr(0,5) == "$nsp ")
{
string new_nsp = line.substr(5);
if(new_nsp == current_socket->get_namespace())
{
continue;
}
current_socket->off_all();
current_socket->off_error();
//per socket.io, default nsp should never been closed.
if(current_socket->get_namespace() != "/")
{
current_socket->close();
}
current_socket = h.socket(new_nsp);
bind_events();
//if change to default nsp, we do not need to login again (since it is not closed).
if(current_socket->get_namespace() == "/")
{
continue;
}
goto Login;
}
current_socket->emit("new message", line);
_lock.lock();
EM("\t\t\t"<<line<<":"<<"You");
_lock.unlock();
}
}
HIGHLIGHT("Closing...");
h.sync_close();
h.clear_con_listeners();
return 0;
}

View File

@@ -0,0 +1 @@
build-*

View File

@@ -0,0 +1,290 @@
![Demo shot](https://cldup.com/98tHyoJJE7.gif)
In this tutorial well learn how to create a QT chat application that communicates with a [Socket.IO Node.JS chat server](https://github.com/Automattic/socket.io/tree/master/examples/chat).
### Introduction
To follow along, start by cloning the repository: [socket.io-client-cpp](https://github.com/socketio/socket.io-client-cpp).
Using:
```bash
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
```
The app has the following features:
* Sending a message to all users joining to the room.
* Notifies when each user joins or leaves.
* Notifies when an user start typing a message.
###Install QT community
Visit [QT community download link](http://www.qt.io/download-open-source/#section-2) to get the install package.
Just install it with default installation option.
###Create a QT GUI application.
Launch QT Creator.
In welcome page, select `New Project`, create a `QT Widget Application`, named it `SioChatDemo`
The project structure is like:
```
SioChatDemo
|__ SioChatDemo.pro
|__Headers
| |__mainwindow.h
|__Sources
| |__main.cpp
| |__mainwindow.cpp
|__Forms
|__mainwindow.ui
```
### Import SioClient and config compile options.
Let's copy the SioClient into the QT project as a subfolder `sioclient`.
Edit `SioChatDemo.pro` to config paths and compile options, simply add:
```bash
SOURCES += ./sioclient/src/sio_client.cpp \
./sioclient/src/sio_packet.cpp
HEADERS += ./sioclient/src/sio_client.h \
./sioclient/src/sio_message.h
INCLUDEPATH += $$PWD/sioclient/lib/rapidjson/include
INCLUDEPATH += $$PWD/sioclient/lib/websocketpp
```
Also add two additional compile option
```bash
CONFIG+=no_keywords
CONFIG+=c++11
```
`no_keywords` is for preventing qmake treat some function's name `emit` as the keyword of signal-slot mechanism.
`c++11` ask for C++11 support.
### Make up mainwindow ui.
Make up a simple ui by drag and drop widget from `Widget box` in left side.
We finally end up with this:
![QT mainwindow](https://cldup.com/RI98CYpYL5.png)
It contains:
* a `QLineEdit` at the top for nickname inputing, named `nickNameEdit`
* a `QPushButton` at the topright for login, named `loginBtn`
* a `QListWidget` at the center for showing messages, named `listView`
* a `QLineEdit` at the bottom for typing message, named `messageEdit`
* a `QPushButton` at the bottomright for sending message, named `sendBtn`
### Add Slots in mainwindow
Slots need to be added in `mainwindow` class to handle UI events.They are
* click login button
* click send message button
* text change in messageEdit(for typing status)
* message editing is returned (for sending message by return)
Insert following code into `MainWindow` class in `mainwindow.h`
```C++
public Q_SLOTS:
void SendBtnClicked();
void TypingChanged();
void LoginClicked();
void OnMessageReturn();
```
### Connect UI event signal and slots together
Open `mainwindow.ui` in Design mode. switch to `signals/slots` mode by check `Menu->Edit->Edit Signals/Slots`
By press left mouse on widget and drag on to the window (cursor will become a sign of electrical ground), to open the connection editor.
In the connection editor, edit the slots of MainWindow at the right side, add Those slots function name added in `mainwindow.h` before.
Then we'll be able to connect the event signal from widget with our own slots.
We finally end up with this:
![QT signals&slots](https://cldup.com/Vsb-UXG3FC.jpg)
### Adding UI refresh Signals/Slots
`sio::client`'s callbacks are not in UI thread. However, UI is required to be updated by those callbacks, so we need some `Signal` for non-UI thread to "request" `Slots` functions been called in UI thread. Say if we want to signal `QListWidgetItem` being added, add:
```C++
//In mainwindow.h
Q_SIGNALS:
void RequestAddListItem(QListWidgetItem *item);
private Q_SLOTS:
void AddListItem(QListWidgetItem *item);
```
```C++
//In mainwindow.cpp
void MainWindow::AddListItem(QListWidgetItem* item)
{
this->findChild<QListWidget*>("listView")->addItem(item);
}
```
Then connect them in `MainWindow` constructor.
```C++
connect(this,SIGNAL(RequestAddListItem(QListWidgetItem*)),this,SLOT(AddListItem(QListWidgetItem*)));
```
### Init sio::client in MainWindow
For single window applications, simply let `MainWindow` class holding the `sio::client` object:
declare a `unique_ptr` member of `sio::client` and Several event handling functions in `mainwindow.h`
```C++
private:
void OnNewMessage(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);
void OnUserJoined(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);
void OnUserLeft(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);
void OnTyping(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);
void OnStopTyping(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);
void OnLogin(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);
void OnConnected();
void OnClosed(client::close_reason const& reason);
void OnFailed();
std::unique_ptr<client> _io;
```
Init `sio::client` and setup event bindings for default `socket` in `MainWindow` constructor.
And we also need to handle the connectivity events, handle the connect and disconnect events.
Now the `MainWindow` constructor:
```C++
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_io(new client())
{
ui->setupUi(this);
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using std::placeholders::_4;
socket::ptr sock = _io->socket();
sock->on("new message",std::bind(&MainWindow::OnNewMessage,this,_1,_2,_3,_4));
sock->on("user joined",std::bind(&MainWindow::OnUserJoined,this,_1,_2,_3,_4));
sock->on("user left",std::bind(&MainWindow::OnUserLeft,this,_1,_2,_3,_4));
sock->on("typing",std::bind(&MainWindow::OnTyping,this,_1,_2,_3,_4));
sock->on("stop typing",std::bind(&MainWindow::OnStopTyping,this,_1,_2,_3,_4));
sock->on("login",std::bind(&MainWindow::OnLogin,this,_1,_2,_3,_4));
//default socket opened, also we have "set_open_listener" for monitoring physical connection opened.
_io->set_socket_open_listener(std::bind(&MainWindow::OnConnected,this,std::placeholders::_1));
//physical connection closed or drop.
_io->set_close_listener(std::bind(&MainWindow::OnClosed,this,_1));
//physical connection fail to establish.
_io->set_fail_listener(std::bind(&MainWindow::OnFailed,this));
connect(this,SIGNAL(RequestAddListItem(QListWidgetItem*)),this,SLOT(AddListItem(QListWidgetItem*)));
}
```
### Managing connection state
We have several connection listeners for connection events.
First we want to send login message once we're connected, get the default `socket` from `client` to do that.
```C++
void MainWindow::OnConnected()
{
QByteArray bytes = m_name.toUtf8();
std::string nickName(bytes.data(),bytes.length());
_io->socket()->emit("add user", nickName);
}
```
Then if connection is closed or failed, we need to restore to the UI before connect.
```C++
void MainWindow::OnClosed(client::close_reason const& reason)
{
//restore UI to pre-login state
}
void MainWindow::OnFailed()
{
//restore UI to pre-login state
}
```
If `MainWindow` is exit, we need to clear event bindings and listeners.
the `sio::client` object will be destruct by `unique_ptr`
```C++
MainWindow::~MainWindow()
{
_io->socket()->off_all();
_io->socket()->off_error();
delete ui;
}
```
### Handle socket.io events
We'll need to handle socket.io events in our functions bind to socket.io events.
For example, we need to show received messages to the `listView`
```C++
void MainWindow::OnNewMessage(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp)
{
if(data->get_flag() == message::flag_object)
{
std::string msg = data->get_map()["message"]->get_string();
std::string name = data->get_map()["username"]->get_string();
QString label = QString::fromUtf8(name.data(),name.length());
label.append(':');
label.append(QString::fromUtf8(msg.data(),msg.length()));
QListWidgetItem *item= new QListWidgetItem(label);
//emit RequestAddListItem signal
//so that 'AddListItem' will be executed in UI thread.
Q_EMIT RequestAddListItem(item);
}
}
```
### Sending chat message
When `sendBtn` is clicked, we need to send the text in `messageEdit` to chatroom.
Add code to `SendBtnClicked()`:
```C++
void MainWindow::SendBtnClicked()
{
QLineEdit* messageEdit = this->findChild<QLineEdit*>("messageEdit");
QString text = messageEdit->text();
if(text.length()>0)
{
QByteArray bytes = text.toUtf8();
std::string msg(bytes.data(),bytes.length());
_io->socket()->emit("new message",msg);//emit new message
text.append(":You");
QListWidgetItem *item = new QListWidgetItem(text);
item->setTextAlignment(Qt::AlignRight);
Q_EMIT RequestAddListItem(item);
messageEdit->clear();
}
}
```
### Further reading
You can run [Demo project](https://github.com/socketio/socket.io-client-cpp/tree/master/examples/QT/SioChatDemo) to have a closer look.
Before running, please follow the [instructions](../../README.md#with_cmake) to make the sioclient library.

View File

@@ -0,0 +1 @@
SioChatDemo.pro.user

View File

@@ -0,0 +1,44 @@
#-------------------------------------------------
#
# Project created by QtCreator 2015-03-30T19:25:23
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = SioChatDemo
TEMPLATE = app
CONFIG+=no_keywords
CONFIG+=c++11
SOURCES += main.cpp\
mainwindow.cpp \
nicknamedialog.cpp
HEADERS += mainwindow.h \
nicknamedialog.h
FORMS += mainwindow.ui \
nicknamedialog.ui
CONFIG(debug, debug|release):DEFINES +=DEBUG=1
INCLUDEPATH += $$PWD/../../../build/include
DEPENDPATH += $$PWD/../../../build/lib
CONFIG(release, debug|release): LIBS += -L$$PWD/../../../build/lib/Release/ -lsioclient
else:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../build/lib/Debug/ -lsioclient
CONFIG(release, debug|release): LIBS += -L$$PWD/../../../build/lib/Release/ -lboost_random
else:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../build/lib/Debug/ -lboost_random
CONFIG(release, debug|release): LIBS += -L$$PWD/../../../build/lib/Release/ -lboost_system
else:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../build/lib/Debug/ -lboost_system
CONFIG(release, debug|release): LIBS += -L$$PWD/../../../build/lib/Release/ -lboost_date_time
else:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../build/lib/Debug/ -lboost_date_time

View File

@@ -0,0 +1,4 @@
osx/*
src/*
src
osx

View File

@@ -0,0 +1,378 @@
#===============================================================================
# Filename: boost.sh
# Author: Pete Goodliffe
# Copyright: (c) Copyright 2009 Pete Goodliffe
# Licence: Please feel free to use this, with attribution
# Modified version
#===============================================================================
#
# Builds a Boost framework for the iPhone.
# Creates a set of universal libraries that can be used on an iPhone and in the
# iPhone simulator. Then creates a pseudo-framework to make using boost in Xcode
# less painful.
#
# To configure the script, define:
# BOOST_LIBS: which libraries to build
# IPHONE_SDKVERSION: iPhone SDK version (e.g. 5.1)
#
# Then go get the source tar.bz of the boost you want to build, shove it in the
# same directory as this script, and run "./boost.sh". Grab a cuppa. And voila.
#===============================================================================
: ${BOOST_LIBS:="random regex graph random chrono thread signals filesystem system date_time"}
: ${IPHONE_SDKVERSION:=`xcodebuild -showsdks | grep iphoneos | egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1`}
: ${OSX_SDKVERSION:=10.8}
: ${XCODE_ROOT:=`xcode-select -print-path`}
: ${EXTRA_CPPFLAGS:="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS -std=c++11 -stdlib=libc++"}
# The EXTRA_CPPFLAGS definition works around a thread race issue in
# shared_ptr. I encountered this historically and have not verified that
# the fix is no longer required. Without using the posix thread primitives
# an invalid compare-and-swap ARM instruction (non-thread-safe) was used for the
# shared_ptr use count causing nasty and subtle bugs.
#
# Should perhaps also consider/use instead: -BOOST_SP_USE_PTHREADS
: ${TARBALLDIR:=`pwd`}
: ${SRCDIR:=`pwd`/src}
: ${IOSBUILDDIR:=`pwd`/ios/build}
: ${OSXBUILDDIR:=`pwd`/osx/build}
: ${PREFIXDIR:=`pwd`/ios/prefix}
: ${IOSFRAMEWORKDIR:=`pwd`/ios/framework}
: ${OSXFRAMEWORKDIR:=`pwd`/osx/framework}
: ${COMPILER:="clang++"}
: ${BOOST_VERSION:=1.55.0}
: ${BOOST_VERSION2:=1_55_0}
BOOST_TARBALL=$TARBALLDIR/boost_$BOOST_VERSION2.tar.bz2
BOOST_SRC=$SRCDIR/boost_${BOOST_VERSION2}
#===============================================================================
ARM_DEV_CMD="xcrun --sdk iphoneos"
SIM_DEV_CMD="xcrun --sdk iphonesimulator"
OSX_DEV_CMD="xcrun --sdk macosx"
ARM_COMBINED_LIB=$IOSBUILDDIR/lib_boost_arm.a
SIM_COMBINED_LIB=$IOSBUILDDIR/lib_boost_x86.a
#===============================================================================
#===============================================================================
# Functions
#===============================================================================
abort()
{
echo
echo "Aborted: $@"
exit 1
}
doneSection()
{
echo
echo "================================================================="
echo "Done"
echo
}
#===============================================================================
cleanEverythingReadyToStart()
{
echo Cleaning everything before we start to build...
rm -rf iphone-build iphonesim-build osx-build
rm -rf $IOSBUILDDIR
rm -rf $OSXBUILDDIR
rm -rf $PREFIXDIR
rm -rf $IOSFRAMEWORKDIR/$FRAMEWORK_NAME.framework
rm -rf $OSXFRAMEWORKDIR/$FRAMEWORK_NAME.framework
doneSection
}
#===============================================================================
downloadBoost()
{
if [ ! -s $TARBALLDIR/boost_${BOOST_VERSION2}.tar.bz2 ]; then
echo "Downloading boost ${BOOST_VERSION}"
curl -L -o $TARBALLDIR/boost_${BOOST_VERSION2}.tar.bz2 http://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION2}.tar.bz2/download
fi
doneSection
}
#===============================================================================
unpackBoost()
{
[ -f "$BOOST_TARBALL" ] || abort "Source tarball missing."
echo Unpacking boost into $SRCDIR...
[ -d $SRCDIR ] || mkdir -p $SRCDIR
[ -d $BOOST_SRC ] || ( cd $SRCDIR; tar xfj $BOOST_TARBALL )
[ -d $BOOST_SRC ] && echo " ...unpacked as $BOOST_SRC"
doneSection
}
#===============================================================================
restoreBoost()
{
cp $BOOST_SRC/tools/build/v2/user-config.jam-bk $BOOST_SRC/tools/build/v2/user-config.jam
}
#===============================================================================
updateBoost()
{
echo Updating boost into $BOOST_SRC...
cp $BOOST_SRC/tools/build/v2/user-config.jam $BOOST_SRC/tools/build/v2/user-config.jam-bk
cat >> $BOOST_SRC/tools/build/v2/user-config.jam <<EOF
using darwin : ${IPHONE_SDKVERSION}~iphone
: $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch armv6 -arch armv7 -arch armv7s -arch arm64 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS
: <striper> <root>$XCODE_ROOT/Platforms/iPhoneOS.platform/Developer
: <architecture>arm <target-os>iphone
;
using darwin : ${IPHONE_SDKVERSION}~iphonesim
: $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch i386 -arch x86_64 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS
: <striper> <root>$XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer
: <architecture>x86 <target-os>iphone
;
EOF
doneSection
}
#===============================================================================
inventMissingHeaders()
{
# These files are missing in the ARM iPhoneOS SDK, but they are in the simulator.
# They are supported on the device, so we copy them from x86 SDK to a staging area
# to use them on ARM, too.
echo Invent missing headers
cp $XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${IPHONE_SDKVERSION}.sdk/usr/include/{crt_externs,bzlib}.h $BOOST_SRC
}
#===============================================================================
bootstrapBoost()
{
cd $BOOST_SRC
BOOST_LIBS_COMMA=$(echo $BOOST_LIBS | sed -e "s/ /,/g")
echo "Bootstrapping (with libs $BOOST_LIBS_COMMA)"
./bootstrap.sh --with-libraries=$BOOST_LIBS_COMMA
doneSection
}
#===============================================================================
buildBoostForIPhoneOS()
{
cd $BOOST_SRC
# Install this one so we can copy the includes for the frameworks...
./bjam -j16 --build-dir=iphone-build --stagedir=iphone-build/stage --prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-${IPHONE_SDKVERSION} define=_LITTLE_ENDIAN link=static stage
./bjam -j16 --build-dir=iphone-build --stagedir=iphone-build/stage --prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-${IPHONE_SDKVERSION} define=_LITTLE_ENDIAN link=static install
doneSection
./bjam -j16 --build-dir=iphonesim-build --stagedir=iphonesim-build/stage --toolset=darwin-${IPHONE_SDKVERSION}~iphonesim architecture=x86 target-os=iphone macosx-version=iphonesim-${IPHONE_SDKVERSION} link=static stage
doneSection
# ./b2 -j16 --build-dir=osx-build --stagedir=osx-build/stage toolset=clang cxxflags="-std=c++11 -stdlib=libc++ -arch i386 -arch x86_64" linkflags="-stdlib=libc++" link=static threading=multi stage
doneSection
}
#===============================================================================
scrunchAllLibsTogetherInOneLibPerPlatform()
{
cd $BOOST_SRC
mkdir -p $IOSBUILDDIR/armv6/obj
mkdir -p $IOSBUILDDIR/armv7/obj
mkdir -p $IOSBUILDDIR/armv7s/obj
mkdir -p $IOSBUILDDIR/arm64/obj
mkdir -p $IOSBUILDDIR/i386/obj
mkdir -p $IOSBUILDDIR/x86_64/obj
mkdir -p $OSXBUILDDIR/i386/obj
mkdir -p $OSXBUILDDIR/x86_64/obj
ALL_LIBS=""
echo Splitting all existing fat binaries...
for NAME in $BOOST_LIBS; do
ALL_LIBS="$ALL_LIBS libboost_$NAME.a"
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv6 -o $IOSBUILDDIR/armv6/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv7 -o $IOSBUILDDIR/armv7/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv7s -o $IOSBUILDDIR/armv7s/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin arm64 -o $IOSBUILDDIR/arm64/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphonesim-build/stage/lib/libboost_$NAME.a" -thin i386 -o $IOSBUILDDIR/i386/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphonesim-build/stage/lib/libboost_$NAME.a" -thin x86_64 -o $IOSBUILDDIR/x86_64/libboost_$NAME.a
$ARM_DEV_CMD lipo "osx-build/stage/lib/libboost_$NAME.a" -thin i386 -o $OSXBUILDDIR/i386/libboost_$NAME.a
$ARM_DEV_CMD lipo "osx-build/stage/lib/libboost_$NAME.a" -thin x86_64 -o $OSXBUILDDIR/x86_64/libboost_$NAME.a
done
echo "Decomposing each architecture's .a files"
for NAME in $ALL_LIBS; do
echo Decomposing $NAME...
(cd $IOSBUILDDIR/armv6/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/armv7/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/armv7s/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/arm64/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/i386/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/x86_64/obj; ar -x ../$NAME );
(cd $OSXBUILDDIR/i386/obj; ar -x ../$NAME );
(cd $OSXBUILDDIR/x86_64/obj; ar -x ../$NAME );
done
echo "Linking each architecture into an uberlib ($ALL_LIBS => libboost.a )"
rm $IOSBUILDDIR/*/libboost.a
echo ...armv6
(cd $IOSBUILDDIR/armv6; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...armv7
(cd $IOSBUILDDIR/armv7; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...armv7s
(cd $IOSBUILDDIR/armv7s; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...arm64
(cd $IOSBUILDDIR/arm64; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...i386
(cd $IOSBUILDDIR/i386; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...x86_64
(cd $IOSBUILDDIR/x86_64; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
rm $OSXBUILDDIR/*/libboost.a
echo ...osx-i386
(cd $OSXBUILDDIR/i386; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...x86_64
(cd $OSXBUILDDIR/x86_64; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
}
#===============================================================================
buildFramework()
{
: ${1:?}
FRAMEWORKDIR=$1
BUILDDIR=$2
VERSION_TYPE=Alpha
FRAMEWORK_NAME=boost
FRAMEWORK_VERSION=A
FRAMEWORK_CURRENT_VERSION=$BOOST_VERSION
FRAMEWORK_COMPATIBILITY_VERSION=$BOOST_VERSION
FRAMEWORK_BUNDLE=$FRAMEWORKDIR/$FRAMEWORK_NAME.framework
echo "Framework: Building $FRAMEWORK_BUNDLE from $BUILDDIR..."
rm -rf $FRAMEWORK_BUNDLE
echo "Framework: Setting up directories..."
mkdir -p $FRAMEWORK_BUNDLE
mkdir -p $FRAMEWORK_BUNDLE/Versions
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Resources
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Headers
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Documentation
echo "Framework: Creating symlinks..."
ln -s $FRAMEWORK_VERSION $FRAMEWORK_BUNDLE/Versions/Current
ln -s Versions/Current/Headers $FRAMEWORK_BUNDLE/Headers
ln -s Versions/Current/Resources $FRAMEWORK_BUNDLE/Resources
ln -s Versions/Current/Documentation $FRAMEWORK_BUNDLE/Documentation
ln -s Versions/Current/$FRAMEWORK_NAME $FRAMEWORK_BUNDLE/$FRAMEWORK_NAME
FRAMEWORK_INSTALL_NAME=$FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/$FRAMEWORK_NAME
echo "Lipoing library into $FRAMEWORK_INSTALL_NAME..."
$ARM_DEV_CMD lipo -create $BUILDDIR/*/libboost.a -o "$FRAMEWORK_INSTALL_NAME" || abort "Lipo $1 failed"
echo "Framework: Copying includes..."
cp -r $PREFIXDIR/include/boost/* $FRAMEWORK_BUNDLE/Headers/
echo "Framework: Creating plist..."
cat > $FRAMEWORK_BUNDLE/Resources/Info.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${FRAMEWORK_NAME}</string>
<key>CFBundleIdentifier</key>
<string>org.boost</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${FRAMEWORK_CURRENT_VERSION}</string>
</dict>
</plist>
EOF
doneSection
}
#===============================================================================
# Execution starts here
#===============================================================================
mkdir -p $IOSBUILDDIR
cleanEverythingReadyToStart #may want to comment if repeatedly running during dev
restoreBoost
echo "BOOST_VERSION: $BOOST_VERSION"
echo "BOOST_LIBS: $BOOST_LIBS"
echo "BOOST_SRC: $BOOST_SRC"
echo "IOSBUILDDIR: $IOSBUILDDIR"
echo "OSXBUILDDIR: $OSXBUILDDIR"
echo "PREFIXDIR: $PREFIXDIR"
echo "IOSFRAMEWORKDIR: $IOSFRAMEWORKDIR"
echo "OSXFRAMEWORKDIR: $OSXFRAMEWORKDIR"
echo "IPHONE_SDKVERSION: $IPHONE_SDKVERSION"
echo "XCODE_ROOT: $XCODE_ROOT"
echo "COMPILER: $COMPILER"
echo
downloadBoost
unpackBoost
inventMissingHeaders
bootstrapBoost
updateBoost
buildBoostForIPhoneOS
scrunchAllLibsTogetherInOneLibPerPlatform
buildFramework $IOSFRAMEWORKDIR $IOSBUILDDIR
buildFramework $OSXFRAMEWORKDIR $OSXBUILDDIR
restoreBoost
echo "Completed successfully"
#===============================================================================

View File

@@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,291 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <functional>
#include <mutex>
#include <cstdlib>
#define kURL "ws://localhost:3000"
#ifdef WIN32
#define BIND_EVENT(IO,EV,FN) \
do{ \
socket::event_listener_aux l = FN;\
IO->on(EV,l);\
} while(0)
#else
#define BIND_EVENT(IO,EV,FN) \
IO->on(EV,FN)
#endif
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_io(new client()),
m_typingItem(NULL),
m_dialog()
{
ui->setupUi(this);
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using std::placeholders::_4;
socket::ptr sock = _io->socket();
BIND_EVENT(sock,"new message",std::bind(&MainWindow::OnNewMessage,this,_1,_2,_3,_4));
BIND_EVENT(sock,"user joined",std::bind(&MainWindow::OnUserJoined,this,_1,_2,_3,_4));
BIND_EVENT(sock,"user left",std::bind(&MainWindow::OnUserLeft,this,_1,_2,_3,_4));
BIND_EVENT(sock,"typing",std::bind(&MainWindow::OnTyping,this,_1,_2,_3,_4));
BIND_EVENT(sock,"stop typing",std::bind(&MainWindow::OnStopTyping,this,_1,_2,_3,_4));
BIND_EVENT(sock,"login",std::bind(&MainWindow::OnLogin,this,_1,_2,_3,_4));
_io->set_socket_open_listener(std::bind(&MainWindow::OnConnected,this,std::placeholders::_1));
_io->set_close_listener(std::bind(&MainWindow::OnClosed,this,_1));
_io->set_fail_listener(std::bind(&MainWindow::OnFailed,this));
connect(this,SIGNAL(RequestAddListItem(QListWidgetItem*)),this,SLOT(AddListItem(QListWidgetItem*)));
connect(this,SIGNAL(RequestRemoveListItem(QListWidgetItem*)),this,SLOT(RemoveListItem(QListWidgetItem*)));
connect(this,SIGNAL(RequestToggleInputs(bool)),this,SLOT(ToggleInputs(bool)));
}
MainWindow::~MainWindow()
{
_io->socket()->off_all();
_io->socket()->off_error();
delete ui;
}
void MainWindow::SendBtnClicked()
{
QLineEdit* messageEdit = this->findChild<QLineEdit*>("messageEdit");
QString text = messageEdit->text();
if(text.length()>0)
{
QByteArray bytes = text.toUtf8();
std::string msg(bytes.data(),bytes.length());
_io->socket()->emit("new message",msg);
text.append(" : You");
QListWidgetItem *item = new QListWidgetItem(text);
item->setTextAlignment(Qt::AlignRight);
Q_EMIT RequestAddListItem(item);
messageEdit->clear();
}
}
void MainWindow::OnMessageReturn()
{
this->SendBtnClicked();
}
void MainWindow::ShowLoginDialog()
{
m_dialog.reset(new NicknameDialog(this));
connect(m_dialog.get(),SIGNAL(accepted()),this,SLOT(NicknameAccept()));
connect(m_dialog.get(),SIGNAL(rejected()),this,SLOT(NicknameCancelled()));
m_dialog->exec();
}
void MainWindow::showEvent(QShowEvent *event)
{
ShowLoginDialog();
}
void MainWindow::TypingStop()
{
m_timer.reset();
_io->socket()->emit("stop typing");
}
void MainWindow::TypingChanged()
{
if(m_timer&&m_timer->isActive())
{
m_timer->stop();
}
else
{
_io->socket()->emit("typing");
}
m_timer.reset(new QTimer(this));
connect(m_timer.get(),SIGNAL(timeout()),this,SLOT(TypingStop()));
m_timer->setSingleShot(true);
m_timer->start(1000);
}
void MainWindow::NicknameAccept()
{
m_name = m_dialog->getNickname();
if(m_name.length()>0)
{
_io->connect(kURL);
}
}
void MainWindow::NicknameCancelled()
{
QApplication::exit();
}
void MainWindow::AddListItem(QListWidgetItem* item)
{
this->findChild<QListWidget*>("listView")->addItem(item);
}
void MainWindow::RemoveListItem(QListWidgetItem* item)
{
QListWidget* list = this->findChild<QListWidget*>("listView");
int row = list->row(item);
delete list->takeItem(row);
}
void MainWindow::OnNewMessage(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp)
{
if(data->get_flag() == message::flag_object)
{
std::string msg = data->get_map()["message"]->get_string();
std::string username = data->get_map()["username"]->get_string();
QString label = QString::fromUtf8(username.data(),username.length());
label.append(" : ");
label.append(QString::fromUtf8(msg.data(),msg.length()));
QListWidgetItem *item= new QListWidgetItem(label);
Q_EMIT RequestAddListItem(item);
}
}
void MainWindow::OnUserJoined(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp)
{
if(data->get_flag() == message::flag_object)
{
std::string name = data->get_map()["username"]->get_string();
int numUser = data->get_map()["numUsers"]->get_int();
QString label = QString::fromUtf8(name.data(),name.length());
bool plural = numUser != 1;
label.append(" joined\n");
label.append(plural?"there are ":"there's ");
QString digits;
while(numUser>=10)
{
digits.insert(0,QChar((numUser%10)+'0'));
numUser/=10;
}
digits.insert(0,QChar(numUser+'0'));
label.append(digits);
label.append(plural?" participants":" participant");
QListWidgetItem *item= new QListWidgetItem(label);
item->setTextAlignment(Qt::AlignHCenter);
QFont font;
font.setPointSize(9);
item->setFont(font);
Q_EMIT RequestAddListItem(item);
}
}
void MainWindow::OnUserLeft(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp)
{
if(data->get_flag() == message::flag_object)
{
std::string name = data->get_map()["username"]->get_string();
int numUser = data->get_map()["numUsers"]->get_int();
QString label = QString::fromUtf8(name.data(),name.length());
bool plural = numUser != 1;
label.append(" left\n");
label.append(plural?"there are ":"there's ");
QString digits;
while(numUser>=10)
{
digits.insert(0,QChar((numUser%10)+'0'));
numUser/=10;
}
digits.insert(0,QChar(numUser+'0'));
label.append(digits);
label.append(plural?" participants":" participant");
QListWidgetItem *item= new QListWidgetItem(label);
item->setTextAlignment(Qt::AlignHCenter);
QFont font;
font.setPointSize(9);
item->setFont(font);
Q_EMIT RequestAddListItem(item);
}
}
void MainWindow::OnTyping(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp)
{
if(m_typingItem == NULL)
{
std::string name = data->get_map()["username"]->get_string();
QString label = QString::fromUtf8(name.data(),name.length());
label.append(" is typing...");
QListWidgetItem *item = new QListWidgetItem(label);
item->setTextColor(QColor(200,200,200,255));
m_typingItem = item;
Q_EMIT RequestAddListItem(item);
}
}
void MainWindow::OnStopTyping(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp)
{
if(m_typingItem != NULL)
{
Q_EMIT RequestRemoveListItem(m_typingItem);
m_typingItem = NULL;
}
}
void MainWindow::OnLogin(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp)
{
Q_EMIT RequestToggleInputs(true);
int numUser = data->get_map()["numUsers"]->get_int();
QString digits;
bool plural = numUser !=1;
while(numUser>=10)
{
digits.insert(0,QChar((numUser%10)+'0'));
numUser/=10;
}
digits.insert(0,QChar(numUser+'0'));
digits.insert(0,plural?"there are ":"there's ");
digits.append(plural? " participants":" participant");
QListWidgetItem *item = new QListWidgetItem(digits);
item->setTextAlignment(Qt::AlignHCenter);
QFont font;
font.setPointSize(9);
item->setFont(font);
Q_EMIT RequestAddListItem(item);
}
void MainWindow::OnConnected(std::string const& nsp)
{
QByteArray bytes = m_name.toUtf8();
std::string nickName(bytes.data(),bytes.length());
_io->socket()->emit("add user", nickName);
}
void MainWindow::OnClosed(client::close_reason const& reason)
{
Q_EMIT RequestToggleInputs(false);
}
void MainWindow::OnFailed()
{
Q_EMIT RequestToggleInputs(false);
}
void MainWindow::ToggleInputs(bool loginOrNot)
{
if(loginOrNot)//already login
{
this->findChild<QWidget*>("messageEdit")->setEnabled(true);
this->findChild<QWidget*>("listView")->setEnabled(true);
// this->findChild<QWidget*>("sendBtn")->setEnabled(true);
}
else
{
this->findChild<QWidget*>("messageEdit")->setEnabled(false);
this->findChild<QWidget*>("listView")->setEnabled(false);
// this->findChild<QWidget*>("sendBtn")->setEnabled(false);
ShowLoginDialog();
}
}

View File

@@ -0,0 +1,68 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QListWidget>
#include <QPushButton>
#include <QPlainTextEdit>
#include <QTimer>
#include <sio_client.h>
#include "nicknamedialog.h"
namespace Ui {
class MainWindow;
}
using namespace sio;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public Q_SLOTS:
void SendBtnClicked();
void TypingChanged();
void OnMessageReturn();
protected:
void showEvent(QShowEvent* event);
Q_SIGNALS:
void RequestAddListItem(QListWidgetItem *item);
void RequestRemoveListItem(QListWidgetItem *item);
void RequestToggleInputs(bool loginOrNot);
private Q_SLOTS:
void AddListItem(QListWidgetItem *item);
void RemoveListItem(QListWidgetItem *item);
void ToggleInputs(bool loginOrNot);
void TypingStop();
void NicknameAccept();
void NicknameCancelled();
private:
void OnNewMessage(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp);
void OnUserJoined(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp);
void OnUserLeft(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp);
void OnTyping(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp);
void OnStopTyping(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp);
void OnLogin(std::string const& name,message::ptr const& data,bool hasAck,message::list &ack_resp);
void OnConnected(std::string const& nsp);
void OnClosed(client::close_reason const& reason);
void OnFailed();
void ShowLoginDialog();
Ui::MainWindow *ui;
std::unique_ptr<client> _io;
std::unique_ptr<NicknameDialog> m_dialog;
QString m_name;
std::unique_ptr<QTimer> m_timer;
QListWidgetItem *m_typingItem;
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<height>549</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Socket.IO Chat</string>
</property>
<property name="unifiedTitleAndToolBarOnMac">
<bool>false</bool>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QListWidget" name="listView">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>8</x>
<y>11</y>
<width>350</width>
<height>461</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
<widget class="QLineEdit" name="messageEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>8</x>
<y>480</y>
<width>350</width>
<height>21</height>
</rect>
</property>
<property name="placeholderText">
<string>Type here...</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections>
<connection>
<sender>messageEdit</sender>
<signal>returnPressed()</signal>
<receiver>MainWindow</receiver>
<slot>OnMessageReturn()</slot>
<hints>
<hint type="sourcelabel">
<x>116</x>
<y>524</y>
</hint>
<hint type="destinationlabel">
<x>30</x>
<y>545</y>
</hint>
</hints>
</connection>
<connection>
<sender>messageEdit</sender>
<signal>textChanged(QString)</signal>
<receiver>MainWindow</receiver>
<slot>TypingChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>73</x>
<y>531</y>
</hint>
<hint type="destinationlabel">
<x>70</x>
<y>510</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>SendBtnClicked(bool)</slot>
<slot>TypingChanged()</slot>
<slot>LoginClicked()</slot>
<slot>OnMessageReturn()</slot>
<slot>SendBtnClicked()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,38 @@
#include "nicknamedialog.h"
#include "ui_nicknamedialog.h"
#include <QTimer>
NicknameDialog::NicknameDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::NicknameDialog)
{
ui->setupUi(this);
}
NicknameDialog::~NicknameDialog()
{
delete ui;
}
const QString& NicknameDialog::getNickname() const
{
return m_nickName;
}
void NicknameDialog::exitApp()
{
QApplication::quit();
}
void NicknameDialog::closeEvent(QCloseEvent *event)
{
QTimer::singleShot(0,this,SLOT(exitApp()));
}
void NicknameDialog::accept()
{
if(this->findChild<QLineEdit*>("nicknameEdit")->text().length()>0)
{
m_nickName = this->findChild<QLineEdit*>("nicknameEdit")->text();
done(QDialog::Accepted);
}
}

View File

@@ -0,0 +1,28 @@
#ifndef NICKNAMEDIALOG_H
#define NICKNAMEDIALOG_H
#include <QDialog>
namespace Ui {
class NicknameDialog;
}
class NicknameDialog : public QDialog
{
Q_OBJECT
public Q_SLOTS:
void accept();
void exitApp();
public:
explicit NicknameDialog(QWidget *parent = 0);
~NicknameDialog();
const QString& getNickname() const;
void closeEvent(QCloseEvent *);
private:
Ui::NicknameDialog *ui;
QString m_nickName;
};
#endif // NICKNAMEDIALOG_H

View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NicknameDialog</class>
<widget class="QDialog" name="NicknameDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<height>151</height>
</rect>
</property>
<property name="windowTitle">
<string>Login</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>30</x>
<y>99</y>
<width>311</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLineEdit" name="nicknameEdit">
<property name="geometry">
<rect>
<x>27</x>
<y>60</y>
<width>311</width>
<height>20</height>
</rect>
</property>
<property name="placeholderText">
<string>Type nickname here...</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>44</x>
<y>23</y>
<width>271</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="text">
<string>What's your nickname?</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>NicknameDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>298</x>
<y>97</y>
</hint>
<hint type="destinationlabel">
<x>298</x>
<y>108</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>NicknameDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>210</x>
<y>125</y>
</hint>
<hint type="destinationlabel">
<x>202</x>
<y>84</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>checkAccept()</slot>
<slot>checkAcc()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,31 @@
#SIOClient iOS chat room demo
## What is this
This is a iOS project run on xcode 6, you can use this single view application chatting in the official [chat room demo](https://github.com/Automattic/socket.io/tree/master/examples/chat).
## How to setup
Suppose you're using your Mac's shell, under your workspace folder, run
```shell
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
```
Step in the demo folder
```shell
cd ./socket.io-client-cpp/examples/iOS/SioChatDemo
```
you will see a shell script named `boost.sh` under folder `boost`,Run
```shell
cd ./boost
bash ./boost.sh
```
Please stand by with patient, this step will take about one or two hours depends on your network.
When done, open `SioChatDemo.xcodeproj` file in the parent folder with xcode.
Just compile and run the `SioChatDemo` target.
Now, if you have your chat room server run on your local machine, you can chat with device to device or device to web.
## Use sioclient as static lib on iOS
There's a target named `sioclient` in the Demo project, That is the exactly right config for buiding the `sioclient` as a static library on iOS.
With the static library file `libsioclient.a` and two exported headers `sio_client.h` and `sio_message.h`, you won't need to config anything again and again in your integrating projects.
## About the `boost.sh`
The `boost.sh` is copied from [boostmake_ios](https://github.com/alist/boostmake_ios),it is worked on my machine for boost 1.55.0
there're lot's versions of boost build shells, you can choose what you like.

View File

@@ -0,0 +1 @@
/**/xcuserdata/

View File

@@ -0,0 +1,722 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
CE1D31A01AD5087800895150 /* sio_packet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE1D319E1AD5087800895150 /* sio_packet.cpp */; };
CE1D31A11AD5087800895150 /* sio_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1D319F1AD5087800895150 /* sio_packet.h */; };
CE2958691ACE4589000ABD30 /* sio_client_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE2958671ACE442F000ABD30 /* sio_client_impl.cpp */; };
CE29586A1ACE4592000ABD30 /* sio_socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE2958621ACE2CD6000ABD30 /* sio_socket.cpp */; };
CE3B3B401AC8F365003CEB94 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CE3B3B3F1AC8F365003CEB94 /* main.m */; };
CE3B3B431AC8F365003CEB94 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE3B3B421AC8F365003CEB94 /* AppDelegate.m */; };
CE3B3B4B1AC8F365003CEB94 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE3B3B4A1AC8F365003CEB94 /* Images.xcassets */; };
CE3B3B4E1AC8F365003CEB94 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3B3B4C1AC8F365003CEB94 /* LaunchScreen.xib */; };
CE3B3B5A1AC8F365003CEB94 /* SioChatDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CE3B3B591AC8F365003CEB94 /* SioChatDemoTests.m */; };
CE3B3B651AC8F385003CEB94 /* CRViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE3B3B641AC8F385003CEB94 /* CRViewController.mm */; };
CE3B3B751AC8F438003CEB94 /* libsioclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE3B3B6A1AC8F438003CEB94 /* libsioclient.a */; };
CE3B3E6D1AC8FE59003CEB94 /* libsioclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE3B3B6A1AC8F438003CEB94 /* libsioclient.a */; };
CE3B3E6F1AC9139B003CEB94 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE3B3E6E1AC9139B003CEB94 /* Main.storyboard */; };
CE3B3E8C1ACA5446003CEB94 /* sio_client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE3B3E871ACA5446003CEB94 /* sio_client.cpp */; };
CE3B3E8D1ACA5446003CEB94 /* sio_client.h in Headers */ = {isa = PBXBuildFile; fileRef = CE3B3E881ACA5446003CEB94 /* sio_client.h */; };
CE3B3E8E1ACA5446003CEB94 /* sio_message.h in Headers */ = {isa = PBXBuildFile; fileRef = CE3B3E891ACA5446003CEB94 /* sio_message.h */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
CE3B3B541AC8F365003CEB94 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = CE3B3B321AC8F365003CEB94 /* Project object */;
proxyType = 1;
remoteGlobalIDString = CE3B3B391AC8F365003CEB94;
remoteInfo = SioChatDemo;
};
CE3B3B761AC8F438003CEB94 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = CE3B3B321AC8F365003CEB94 /* Project object */;
proxyType = 1;
remoteGlobalIDString = CE3B3B691AC8F438003CEB94;
remoteInfo = sioclient;
};
CE3B3E6B1AC8FE54003CEB94 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = CE3B3B321AC8F365003CEB94 /* Project object */;
proxyType = 1;
remoteGlobalIDString = CE3B3B691AC8F438003CEB94;
remoteInfo = sioclient;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
CE3B3B681AC8F438003CEB94 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
CE1D319E1AD5087800895150 /* sio_packet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sio_packet.cpp; sourceTree = "<group>"; };
CE1D319F1AD5087800895150 /* sio_packet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sio_packet.h; sourceTree = "<group>"; };
CE2958621ACE2CD6000ABD30 /* sio_socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sio_socket.cpp; sourceTree = "<group>"; };
CE2958631ACE2CD6000ABD30 /* sio_socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sio_socket.h; sourceTree = "<group>"; };
CE2958661ACE2CDD000ABD30 /* sio_client_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sio_client_impl.h; sourceTree = "<group>"; };
CE2958671ACE442F000ABD30 /* sio_client_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sio_client_impl.cpp; sourceTree = "<group>"; };
CE3B3B3A1AC8F365003CEB94 /* SioChatDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SioChatDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
CE3B3B3E1AC8F365003CEB94 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CE3B3B3F1AC8F365003CEB94 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
CE3B3B411AC8F365003CEB94 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
CE3B3B421AC8F365003CEB94 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
CE3B3B4A1AC8F365003CEB94 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
CE3B3B4D1AC8F365003CEB94 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
CE3B3B531AC8F365003CEB94 /* SioChatDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SioChatDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
CE3B3B581AC8F365003CEB94 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CE3B3B591AC8F365003CEB94 /* SioChatDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SioChatDemoTests.m; sourceTree = "<group>"; };
CE3B3B631AC8F385003CEB94 /* CRViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRViewController.h; sourceTree = "<group>"; };
CE3B3B641AC8F385003CEB94 /* CRViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CRViewController.mm; sourceTree = "<group>"; };
CE3B3B6A1AC8F438003CEB94 /* libsioclient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsioclient.a; sourceTree = BUILT_PRODUCTS_DIR; };
CE3B3B741AC8F438003CEB94 /* sioclientTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = sioclientTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
CE3B3B7A1AC8F438003CEB94 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CE3B3E6E1AC9139B003CEB94 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
CE3B3E871ACA5446003CEB94 /* sio_client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sio_client.cpp; sourceTree = "<group>"; };
CE3B3E881ACA5446003CEB94 /* sio_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sio_client.h; sourceTree = "<group>"; };
CE3B3E891ACA5446003CEB94 /* sio_message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sio_message.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CE3B3B371AC8F365003CEB94 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CE3B3E6D1AC8FE59003CEB94 /* libsioclient.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B501AC8F365003CEB94 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B671AC8F438003CEB94 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B711AC8F438003CEB94 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CE3B3B751AC8F438003CEB94 /* libsioclient.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
CE2958651ACE2CDD000ABD30 /* internal */ = {
isa = PBXGroup;
children = (
CE1D319E1AD5087800895150 /* sio_packet.cpp */,
CE1D319F1AD5087800895150 /* sio_packet.h */,
CE2958661ACE2CDD000ABD30 /* sio_client_impl.h */,
CE2958671ACE442F000ABD30 /* sio_client_impl.cpp */,
);
path = internal;
sourceTree = "<group>";
};
CE3B3B311AC8F365003CEB94 = {
isa = PBXGroup;
children = (
CE3B3E861ACA5446003CEB94 /* src */,
CE3B3B3C1AC8F365003CEB94 /* SioChatDemo */,
CE3B3B561AC8F365003CEB94 /* SioChatDemoTests */,
CE3B3B6B1AC8F438003CEB94 /* sioclient */,
CE3B3B781AC8F438003CEB94 /* sioclientTests */,
CE3B3B3B1AC8F365003CEB94 /* Products */,
);
sourceTree = "<group>";
};
CE3B3B3B1AC8F365003CEB94 /* Products */ = {
isa = PBXGroup;
children = (
CE3B3B3A1AC8F365003CEB94 /* SioChatDemo.app */,
CE3B3B531AC8F365003CEB94 /* SioChatDemoTests.xctest */,
CE3B3B6A1AC8F438003CEB94 /* libsioclient.a */,
CE3B3B741AC8F438003CEB94 /* sioclientTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
CE3B3B3C1AC8F365003CEB94 /* SioChatDemo */ = {
isa = PBXGroup;
children = (
CE3B3E6E1AC9139B003CEB94 /* Main.storyboard */,
CE3B3B411AC8F365003CEB94 /* AppDelegate.h */,
CE3B3B421AC8F365003CEB94 /* AppDelegate.m */,
CE3B3B631AC8F385003CEB94 /* CRViewController.h */,
CE3B3B641AC8F385003CEB94 /* CRViewController.mm */,
CE3B3B4A1AC8F365003CEB94 /* Images.xcassets */,
CE3B3B4C1AC8F365003CEB94 /* LaunchScreen.xib */,
CE3B3B3D1AC8F365003CEB94 /* Supporting Files */,
);
path = SioChatDemo;
sourceTree = "<group>";
};
CE3B3B3D1AC8F365003CEB94 /* Supporting Files */ = {
isa = PBXGroup;
children = (
CE3B3B3E1AC8F365003CEB94 /* Info.plist */,
CE3B3B3F1AC8F365003CEB94 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
CE3B3B561AC8F365003CEB94 /* SioChatDemoTests */ = {
isa = PBXGroup;
children = (
CE3B3B591AC8F365003CEB94 /* SioChatDemoTests.m */,
CE3B3B571AC8F365003CEB94 /* Supporting Files */,
);
path = SioChatDemoTests;
sourceTree = "<group>";
};
CE3B3B571AC8F365003CEB94 /* Supporting Files */ = {
isa = PBXGroup;
children = (
CE3B3B581AC8F365003CEB94 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
CE3B3B6B1AC8F438003CEB94 /* sioclient */ = {
isa = PBXGroup;
children = (
);
path = sioclient;
sourceTree = "<group>";
};
CE3B3B781AC8F438003CEB94 /* sioclientTests */ = {
isa = PBXGroup;
children = (
CE3B3B791AC8F438003CEB94 /* Supporting Files */,
);
path = sioclientTests;
sourceTree = "<group>";
};
CE3B3B791AC8F438003CEB94 /* Supporting Files */ = {
isa = PBXGroup;
children = (
CE3B3B7A1AC8F438003CEB94 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
CE3B3E861ACA5446003CEB94 /* src */ = {
isa = PBXGroup;
children = (
CE2958651ACE2CDD000ABD30 /* internal */,
CE2958621ACE2CD6000ABD30 /* sio_socket.cpp */,
CE2958631ACE2CD6000ABD30 /* sio_socket.h */,
CE3B3E871ACA5446003CEB94 /* sio_client.cpp */,
CE3B3E881ACA5446003CEB94 /* sio_client.h */,
CE3B3E891ACA5446003CEB94 /* sio_message.h */,
);
name = src;
path = ../../../src;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
CE3B3E681AC8F511003CEB94 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
CE3B3E8E1ACA5446003CEB94 /* sio_message.h in Headers */,
CE1D31A11AD5087800895150 /* sio_packet.h in Headers */,
CE3B3E8D1ACA5446003CEB94 /* sio_client.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
CE3B3B391AC8F365003CEB94 /* SioChatDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = CE3B3B5D1AC8F365003CEB94 /* Build configuration list for PBXNativeTarget "SioChatDemo" */;
buildPhases = (
CE3B3B361AC8F365003CEB94 /* Sources */,
CE3B3B371AC8F365003CEB94 /* Frameworks */,
CE3B3B381AC8F365003CEB94 /* Resources */,
);
buildRules = (
);
dependencies = (
CE3B3E6C1AC8FE54003CEB94 /* PBXTargetDependency */,
);
name = SioChatDemo;
productName = SioChatDemo;
productReference = CE3B3B3A1AC8F365003CEB94 /* SioChatDemo.app */;
productType = "com.apple.product-type.application";
};
CE3B3B521AC8F365003CEB94 /* SioChatDemoTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = CE3B3B601AC8F365003CEB94 /* Build configuration list for PBXNativeTarget "SioChatDemoTests" */;
buildPhases = (
CE3B3B4F1AC8F365003CEB94 /* Sources */,
CE3B3B501AC8F365003CEB94 /* Frameworks */,
CE3B3B511AC8F365003CEB94 /* Resources */,
);
buildRules = (
);
dependencies = (
CE3B3B551AC8F365003CEB94 /* PBXTargetDependency */,
);
name = SioChatDemoTests;
productName = SioChatDemoTests;
productReference = CE3B3B531AC8F365003CEB94 /* SioChatDemoTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
CE3B3B691AC8F438003CEB94 /* sioclient */ = {
isa = PBXNativeTarget;
buildConfigurationList = CE3B3B7B1AC8F438003CEB94 /* Build configuration list for PBXNativeTarget "sioclient" */;
buildPhases = (
CE3B3B661AC8F438003CEB94 /* Sources */,
CE3B3B671AC8F438003CEB94 /* Frameworks */,
CE3B3B681AC8F438003CEB94 /* CopyFiles */,
CE3B3E681AC8F511003CEB94 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = sioclient;
productName = sioclient;
productReference = CE3B3B6A1AC8F438003CEB94 /* libsioclient.a */;
productType = "com.apple.product-type.library.static";
};
CE3B3B731AC8F438003CEB94 /* sioclientTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = CE3B3B7E1AC8F438003CEB94 /* Build configuration list for PBXNativeTarget "sioclientTests" */;
buildPhases = (
CE3B3B701AC8F438003CEB94 /* Sources */,
CE3B3B711AC8F438003CEB94 /* Frameworks */,
CE3B3B721AC8F438003CEB94 /* Resources */,
);
buildRules = (
);
dependencies = (
CE3B3B771AC8F438003CEB94 /* PBXTargetDependency */,
);
name = sioclientTests;
productName = sioclientTests;
productReference = CE3B3B741AC8F438003CEB94 /* sioclientTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CE3B3B321AC8F365003CEB94 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Melo Yao";
TargetAttributes = {
CE3B3B391AC8F365003CEB94 = {
CreatedOnToolsVersion = 6.1.1;
};
CE3B3B521AC8F365003CEB94 = {
CreatedOnToolsVersion = 6.1.1;
TestTargetID = CE3B3B391AC8F365003CEB94;
};
CE3B3B691AC8F438003CEB94 = {
CreatedOnToolsVersion = 6.1.1;
};
CE3B3B731AC8F438003CEB94 = {
CreatedOnToolsVersion = 6.1.1;
};
};
};
buildConfigurationList = CE3B3B351AC8F365003CEB94 /* Build configuration list for PBXProject "SioChatDemo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CE3B3B311AC8F365003CEB94;
productRefGroup = CE3B3B3B1AC8F365003CEB94 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CE3B3B391AC8F365003CEB94 /* SioChatDemo */,
CE3B3B521AC8F365003CEB94 /* SioChatDemoTests */,
CE3B3B691AC8F438003CEB94 /* sioclient */,
CE3B3B731AC8F438003CEB94 /* sioclientTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
CE3B3B381AC8F365003CEB94 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CE3B3E6F1AC9139B003CEB94 /* Main.storyboard in Resources */,
CE3B3B4E1AC8F365003CEB94 /* LaunchScreen.xib in Resources */,
CE3B3B4B1AC8F365003CEB94 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B511AC8F365003CEB94 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B721AC8F438003CEB94 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CE3B3B361AC8F365003CEB94 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CE3B3B431AC8F365003CEB94 /* AppDelegate.m in Sources */,
CE3B3B401AC8F365003CEB94 /* main.m in Sources */,
CE3B3B651AC8F385003CEB94 /* CRViewController.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B4F1AC8F365003CEB94 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CE3B3B5A1AC8F365003CEB94 /* SioChatDemoTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B661AC8F438003CEB94 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CE29586A1ACE4592000ABD30 /* sio_socket.cpp in Sources */,
CE1D31A01AD5087800895150 /* sio_packet.cpp in Sources */,
CE2958691ACE4589000ABD30 /* sio_client_impl.cpp in Sources */,
CE3B3E8C1ACA5446003CEB94 /* sio_client.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CE3B3B701AC8F438003CEB94 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
CE3B3B551AC8F365003CEB94 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CE3B3B391AC8F365003CEB94 /* SioChatDemo */;
targetProxy = CE3B3B541AC8F365003CEB94 /* PBXContainerItemProxy */;
};
CE3B3B771AC8F438003CEB94 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CE3B3B691AC8F438003CEB94 /* sioclient */;
targetProxy = CE3B3B761AC8F438003CEB94 /* PBXContainerItemProxy */;
};
CE3B3E6C1AC8FE54003CEB94 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CE3B3B691AC8F438003CEB94 /* sioclient */;
targetProxy = CE3B3E6B1AC8FE54003CEB94 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
CE3B3B4C1AC8F365003CEB94 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
CE3B3B4D1AC8F365003CEB94 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
CE3B3B5B1AC8F365003CEB94 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
CE3B3B5C1AC8F365003CEB94 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
CE3B3B5E1AC8F365003CEB94 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = SioChatDemo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
CE3B3B5F1AC8F365003CEB94 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = SioChatDemo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
CE3B3B611AC8F365003CEB94 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = SioChatDemoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SioChatDemo.app/SioChatDemo";
};
name = Debug;
};
CE3B3B621AC8F365003CEB94 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = SioChatDemoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SioChatDemo.app/SioChatDemo";
};
name = Release;
};
CE3B3B7C1AC8F438003CEB94 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SIOROOT)/lib/websocketpp",
"$(SIOROOT)/lib/rapidjson/include",
"$(SRCROOT)/boost/ios/prefix/include",
);
LIBRARY_SEARCH_PATHS = "$(SRCROOT)/boost/ios/build/$(CURRENT_ARCH)/";
OTHER_LDFLAGS = "-ObjC";
OTHER_LIBTOOLFLAGS = "-lboost_random -lboost_date_time -lboost_system";
PRODUCT_NAME = "$(TARGET_NAME)";
SIOROOT = "$(SRCROOT)/../../../";
SKIP_INSTALL = YES;
};
name = Debug;
};
CE3B3B7D1AC8F438003CEB94 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SIOROOT)/lib/websocketpp",
"$(SIOROOT)/lib/rapidjson/include",
"$(SRCROOT)/boost/ios/prefix/include",
);
LIBRARY_SEARCH_PATHS = "$(SRCROOT)/boost/ios/build/$(CURRENT_ARCH)/";
OTHER_LDFLAGS = "-ObjC";
OTHER_LIBTOOLFLAGS = "-lboost_random -lboost_date_time -lboost_system";
PRODUCT_NAME = "$(TARGET_NAME)";
SIOROOT = "$(SRCROOT)/../../../";
SKIP_INSTALL = YES;
};
name = Release;
};
CE3B3B7F1AC8F438003CEB94 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = sioclientTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
CE3B3B801AC8F438003CEB94 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = sioclientTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CE3B3B351AC8F365003CEB94 /* Build configuration list for PBXProject "SioChatDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CE3B3B5B1AC8F365003CEB94 /* Debug */,
CE3B3B5C1AC8F365003CEB94 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CE3B3B5D1AC8F365003CEB94 /* Build configuration list for PBXNativeTarget "SioChatDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CE3B3B5E1AC8F365003CEB94 /* Debug */,
CE3B3B5F1AC8F365003CEB94 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CE3B3B601AC8F365003CEB94 /* Build configuration list for PBXNativeTarget "SioChatDemoTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CE3B3B611AC8F365003CEB94 /* Debug */,
CE3B3B621AC8F365003CEB94 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CE3B3B7B1AC8F438003CEB94 /* Build configuration list for PBXNativeTarget "sioclient" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CE3B3B7C1AC8F438003CEB94 /* Debug */,
CE3B3B7D1AC8F438003CEB94 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CE3B3B7E1AC8F438003CEB94 /* Build configuration list for PBXNativeTarget "sioclientTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CE3B3B7F1AC8F438003CEB94 /* Debug */,
CE3B3B801AC8F438003CEB94 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CE3B3B321AC8F365003CEB94 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:SioChatDemo.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>F1CE472E-3AF3-4EDA-9B64-F9DD83C665BC</string>
<key>IDESourceControlProjectName</key>
<string>SioChatDemo</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>21C71CD5ED4B8C77974DDBAF056104F039A3B593</key>
<string>https://github.com/socketio/socket.io-client-cpp.git</string>
<key>7448E718372DB7A4B0D01E27524ED3F8AE51A902</key>
<string>https://github.com/miloyip/rapidjson.git</string>
<key>995AABD49A028E610D29FFC44D560D9DAC1EAC0B</key>
<string>https://github.com/zaphoyd/websocketpp.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>examples/iOS/SioChatDemo/SioChatDemo.xcodeproj</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>21C71CD5ED4B8C77974DDBAF056104F039A3B593</key>
<string>../../../../..</string>
<key>7448E718372DB7A4B0D01E27524ED3F8AE51A902</key>
<string>../../../../..lib/rapidjson</string>
<key>995AABD49A028E610D29FFC44D560D9DAC1EAC0B</key>
<string>../../../../..lib/websocketpp</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>https://github.com/socketio/socket.io-client-cpp.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>21C71CD5ED4B8C77974DDBAF056104F039A3B593</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>7448E718372DB7A4B0D01E27524ED3F8AE51A902</string>
<key>IDESourceControlWCCName</key>
<string>rapidjson</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>21C71CD5ED4B8C77974DDBAF056104F039A3B593</string>
<key>IDESourceControlWCCName</key>
<string>sioclient</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>995AABD49A028E610D29FFC44D560D9DAC1EAC0B</string>
<key>IDESourceControlWCCName</key>
<string>websocketpp</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,17 @@
//
// AppDelegate.h
// SioChatDemo
//
// Created by Melo Yao on 3/30/15.
// Copyright (c) 2015 Melo Yao. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -0,0 +1,45 @@
//
// AppDelegate.m
// SioChatDemo
//
// Created by Melo Yao on 3/30/15.
// Copyright (c) 2015 Melo Yao. All rights reserved.
//
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Melo Yao. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SioChatDemo" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

View File

@@ -0,0 +1,12 @@
//
// CRViewController.h
// ChatRoom
//
// Created by Melo Yao on 3/30/15.
//
#import <UIKit/UIKit.h>
@interface CRViewController : UIViewController
@end

View File

@@ -0,0 +1,453 @@
//
// CRViewController.m
// ChatRoom
//
// Created by Melo Yao on 3/30/15.
//
#import "CRViewController.h"
#include "sio_client.h"
typedef enum MessageFlag
{
Message_System,
Message_Other,
Message_You
};
@interface MessageItem : NSObject
@property NSString* message;
@property MessageFlag flag; //0 system info, 1 other message, 2 your message
@end
@implementation MessageItem
@end
@interface CRViewController ()<UITableViewDataSource,UITableViewDelegate,NSURLConnectionDelegate,NSURLConnectionDataDelegate,UITextFieldDelegate>
{
sio::client *_io;
NSMutableArray *_receivedMessage;
NSMutableSet *_typingUsers;
NSString* _name;
NSInteger _userCount;
NSTimer* _inputTimer;
}
@property (weak, nonatomic) IBOutlet UILabel *infoLabel;
@property (weak, nonatomic) IBOutlet UILabel *typingLabel;
@property (strong, nonatomic) IBOutlet UIView *loginPage;
@property (weak, nonatomic) IBOutlet UITextField *nickName;
- (IBAction)onSend:(id)sender;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIButton *sendBtn;
@property (weak, nonatomic) IBOutlet UITextField *messageField;
@property (weak, nonatomic) IBOutlet UIView *messageArea;
-(void)onNewMessage:(NSString*) message from:(NSString*) name;
-(void)onUserJoined:(NSString*)user participants:(NSInteger) num;
-(void)onUserLeft:(NSString*) user participants:(NSInteger) num;
-(void)onUserTyping:(NSString*) user;
-(void)onUserStopTyping:(NSString*) user;
-(void)onLogin:(NSInteger) numParticipants;
-(void)onConnected;
-(void)onDisconnected;
-(void) updateUser:(NSString*)user count:(NSInteger) num joinOrLeft:(BOOL) isJoin;
@end
using namespace std;
using namespace sio;
void OnNewMessage(CFTypeRef ctrl,string const& name,sio::message::ptr const& data,bool needACK,sio::message::list ackResp)
{
if(data->get_flag() == message::flag_object)
{
NSString* msg = [NSString stringWithUTF8String:data->get_map()["message"]->get_string().data()];
NSString* user = [NSString stringWithUTF8String:data->get_map()["username"]->get_string().data()];
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onNewMessage:msg from:user];
});
}
}
void OnTyping(CFTypeRef ctrl,string const& name,sio::message::ptr const& data,bool needACK,sio::message::list ackResp)
{
if(data->get_flag() == message::flag_object)
{
NSString* user = [NSString stringWithUTF8String:data->get_map()["username"]->get_string().data()];
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onUserTyping:user];
});
}
}
void OnStopTyping(CFTypeRef ctrl,string const& name,sio::message::ptr const& data,bool needACK,sio::message::list ackResp)
{
if(data->get_flag() == message::flag_object)
{
NSString* user = [NSString stringWithUTF8String:data->get_map()["username"]->get_string().data()];
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onUserStopTyping:user];
});
}
}
void OnUserJoined(CFTypeRef ctrl, string const& name, sio::message::ptr const& data, bool needACK, sio::message::list ackResp)
{
if(data->get_flag() == message::flag_object)
{
NSString* user = [NSString stringWithUTF8String:data->get_map()["username"]->get_string().data()];
NSInteger num = data->get_map()["numUsers"]->get_int();
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onUserJoined:user participants:num];
});
}
}
void OnUserLeft(CFTypeRef ctrl, string const& name, sio::message::ptr const& data, bool needACK, sio::message::list ackResp)
{
if(data->get_flag() == message::flag_object)
{
NSString* user = [NSString stringWithUTF8String:data->get_map()["username"]->get_string().data()];
NSInteger num = data->get_map()["numUsers"]->get_int();
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onUserLeft:user participants:num];
});
}
}
void OnLogin(CFTypeRef ctrl, string const& name, sio::message::ptr const& data, bool needACK, sio::message::list ackResp)
{
if(data->get_flag() == message::flag_object)
{
NSInteger num = data->get_map()["numUsers"]->get_int();
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onLogin:num];
});
}
}
void OnConnected(CFTypeRef ctrl,std::string nsp)
{
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onConnected];
});
}
void OnFailed(CFTypeRef ctrl)
{
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onDisconnected];
});
}
void OnClose(CFTypeRef ctrl,sio::client::close_reason const& reason)
{
dispatch_async(dispatch_get_main_queue(), ^{
[((__bridge CRViewController*)ctrl) onDisconnected];
});
}
@implementation CRViewController
-(void)awakeFromNib
{
_receivedMessage = [NSMutableArray array];
_typingUsers = [NSMutableSet set];
_io = new sio::client();
[self.loginPage setFrame:self.view.bounds];
[self.view addSubview:self.loginPage];
self.nickName.enabled = YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewWillAppear:(BOOL)animated
{
_io->set_socket_open_listener(std::bind(&OnConnected, (__bridge CFTypeRef)self,std::placeholders::_1));
_io->set_close_listener(std::bind(&OnClose, (__bridge CFTypeRef)self, std::placeholders::_1));
_io->set_fail_listener(std::bind(&OnFailed, (__bridge CFTypeRef)self));
}
-(void)keyboardWillShow:(NSNotification*)notification
{
CGFloat height = [[notification.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;
// Animate the current view out of the way
[UIView animateWithDuration:0.35 animations:^{
self.messageArea.transform = CGAffineTransformMakeTranslation(0, -height);
}];
}
-(void)keyboardWillHide {
[UIView animateWithDuration:0.35 animations:^{
self.messageArea.transform = CGAffineTransformIdentity;
}];
}
-(void)viewDidDisappear:(BOOL)animated
{
_io->socket()->off_all();
_io->set_open_listener(nullptr);
_io->set_close_listener(nullptr);
_io->close();
}
-(void)onNewMessage:(NSString*) message from:(NSString*) name
{
MessageItem *item = [[MessageItem alloc] init];
item.flag = [name isEqualToString:_name]?Message_You:Message_Other;
item.message = item.flag == Message_You? [NSString stringWithFormat:@"%@:%@",message,name]:[NSString stringWithFormat:@"%@:%@",name,message];
[_receivedMessage addObject:item];
[_tableView reloadData];
if(![_messageField isFirstResponder])
{
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[_receivedMessage count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
-(void)onUserJoined:(NSString*)user participants:(NSInteger) num
{
_userCount = num;
[self updateUser:user count:num joinOrLeft:YES];
}
-(void)onUserLeft:(NSString*) user participants:(NSInteger) num
{
[_typingUsers removeObject:user];//protective removal.
[self updateTyping];
_userCount = num;
[self updateUser:user count:num joinOrLeft:NO];
}
-(void)onUserTyping:(NSString*) user
{
[_typingUsers addObject:user];
[self updateTyping];
}
-(void)onUserStopTyping:(NSString*) user
{
[_typingUsers removeObject:user];
[self updateTyping];
}
-(void)onLogin:(NSInteger) numParticipants
{
_name = _nickName.text;
_userCount = numParticipants;
[self.loginPage removeFromSuperview];
[self updateUser:nil count:_userCount joinOrLeft:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)onSend:(id)sender {
if ([_messageField.text length]>0 && [_name length]>0) {
_io->socket()->emit("new message",[_messageField.text UTF8String]);
MessageItem *item = [[MessageItem alloc] init];
item.flag = Message_You;
item.message = [NSString stringWithFormat:@"%@:You",_messageField.text];
[_receivedMessage addObject:item];
[_tableView reloadData];
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[_receivedMessage count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
self.messageField.text = nil;
[self.messageField resignFirstResponder];
}
-(void)onConnected
{
_io->socket()->emit("add user", [self.nickName.text UTF8String]);
}
-(void)onDisconnected
{
if([self.loginPage superview] == nil)
{
[self.view addSubview:self.loginPage];
}
self.nickName.enabled = YES;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
-(void) updateUser:(NSString*)user count:(NSInteger) num joinOrLeft:(BOOL) isJoin
{
_userCount = num;
MessageItem *item = [[MessageItem alloc] init];
item.flag = Message_System;
if (user) {
item.message = [NSString stringWithFormat:@"%@ %@\n%@",user,isJoin?@"joined":@"left",num==1?@"there's 1 participant":[NSString stringWithFormat:@"there are %ld participants",num]];
}
else
{
item.message = [NSString stringWithFormat:@"Welcome to Socket.IO Chat-\n%@",num==1?@"there's 1 participant":[NSString stringWithFormat:@"there are %ld participants",num]];
}
[_receivedMessage addObject:item];
[_tableView reloadData];
if(![_messageField isFirstResponder])
{
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[_receivedMessage count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
-(void) inputTimeout
{
_inputTimer = nil;
_io->socket()->emit("stop typing", "");
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField == self.messageField)
{
if(_inputTimer.valid)
{
[_inputTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
}
else
{
_io->socket()->emit("typing", "");
_inputTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(inputTimeout) userInfo:nil repeats:NO];
}
}
return YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_receivedMessage count];
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Msg"];
MessageItem* item = [_receivedMessage objectAtIndex:indexPath.row];
cell.textLabel.text = item.message;
switch (item.flag) {
case Message_System:
cell.textLabel.textAlignment = NSTextAlignmentCenter;
[cell.textLabel setFont:[UIFont fontWithName:[cell.textLabel.font fontName] size:12]];
break;
case Message_Other:
[cell.textLabel setFont:[UIFont fontWithName:[cell.textLabel.font fontName] size:15]];
cell.textLabel.textAlignment = NSTextAlignmentLeft;
break;
case Message_You:
[cell.textLabel setFont:[UIFont fontWithName:[cell.textLabel.font fontName] size:15]];
cell.textLabel.textAlignment = NSTextAlignmentRight;
break;
default:
break;
}
return cell;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if ([self.messageField isFirstResponder]) {
[self.messageField resignFirstResponder];
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == self.nickName) {
if ([self.nickName.text length] > 0) {
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using std::placeholders::_4;
socket::ptr socket = _io->socket();
socket->on("new message", std::bind(&OnNewMessage, (__bridge CFTypeRef)self, _1,_2,_3,_4));
socket->on("typing", std::bind(&OnTyping, (__bridge CFTypeRef)self, _1,_2,_3,_4));
socket->on("stop typing", std::bind(&OnStopTyping, (__bridge CFTypeRef)self, _1,_2,_3,_4));
socket->on("user joined", std::bind(&OnUserJoined, (__bridge CFTypeRef)self, _1,_2,_3,_4));
socket->on("user left", std::bind(&OnUserLeft, (__bridge CFTypeRef)self, _1,_2,_3,_4));
socket->on("login", std::bind(&OnLogin, (__bridge CFTypeRef)self, _1,_2,_3,_4));
_io->connect("ws://localhost:3000");
self.nickName.enabled = NO;
}
}
else if(textField == self.messageField)
{
[self onSend:textField];
}
return YES;
}
-(void)updateTyping
{
NSString* typingMsg = nil;
NSString* name = [_typingUsers anyObject];
if (name) {
if([_typingUsers count]>1)
{
typingMsg = [NSString stringWithFormat:@"%@ and %ld more are typing",name,[_typingUsers count]];
}
else
{
typingMsg =[NSString stringWithFormat:@"%@ is typing",name];
}
}
self.typingLabel.text = typingMsg;
}
- (void)dealloc
{
delete _io;
}
@end

View File

@@ -0,0 +1,68 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.socketio.melode.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="FVA-Ip-uIE">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="4B5-FI-8YR">
<objects>
<viewController id="FVA-Ip-uIE" customClass="CRViewController" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="j56-Sc-Uve">
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="Zd9-dA-z1N">
<rect key="frame" x="0.0" y="20" width="320" height="396"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Msg" textLabel="c7q-ly-Hf0" style="IBUITableViewCellStyleDefault" id="13Y-SW-wci">
<rect key="frame" x="0.0" y="22" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="13Y-SW-wci" id="CkG-vX-yh5">
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="c7q-ly-Hf0">
<rect key="frame" x="15" y="0.0" width="290" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="18"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="FVA-Ip-uIE" id="gbf-ws-uXu"/>
<outlet property="delegate" destination="FVA-Ip-uIE" id="Y5j-aM-c5q"/>
</connections>
</tableView>
<view contentMode="scaleToFill" id="yh5-ME-DKM">
<rect key="frame" x="0.0" y="416" width="320" height="64"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Type here..." minimumFontSize="17" id="Eq9-78-qhY">
<rect key="frame" x="8" y="26" width="250" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="14"/>
<textInputTraits key="textInputTraits" returnKeyType="send"/>
<connections>
<outlet property="delegate" destination="FVA-Ip-uIE" id="tUP-2R-seQ"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="wwz-tj-MLo">
<rect key="frame" x="8" y="3" width="250" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="14"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="WZS-UQ-rXy">
<rect key="frame" x="266" y="30" width="46" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="18"/>
<state key="normal" title="Send">
<color key="titleColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onSend:" destination="FVA-Ip-uIE" eventType="touchUpInside" id="0VT-Nd-fdz"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="tintColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
<extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
<connections>
<outlet property="loginPage" destination="FDy-KL-ozA" id="zBO-Gk-9OU"/>
<outlet property="messageArea" destination="yh5-ME-DKM" id="nFQ-Zd-Gmx"/>
<outlet property="messageField" destination="Eq9-78-qhY" id="HDE-p4-jGM"/>
<outlet property="nickName" destination="Xat-ec-Oga" id="xyE-A7-aZ5"/>
<outlet property="sendBtn" destination="WZS-UQ-rXy" id="nbZ-e0-RoK"/>
<outlet property="tableView" destination="Zd9-dA-z1N" id="Ekd-Is-nd5"/>
<outlet property="typingLabel" destination="wwz-tj-MLo" id="GxR-Bb-TGT"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="X4s-OP-QGg" userLabel="First Responder" sceneMemberID="firstResponder"/>
<view contentMode="scaleToFill" id="FDy-KL-ozA">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Your Nickname:" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Vbn-qK-OOg">
<rect key="frame" x="40" y="200" width="240" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" id="Xat-ec-Oga">
<rect key="frame" x="40" y="269" width="240" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="16"/>
<textInputTraits key="textInputTraits" returnKeyType="done"/>
<connections>
<outlet property="delegate" destination="FVA-Ip-uIE" id="fDd-Hi-o32"/>
</connections>
</textField>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
</objects>
<point key="canvasLocation" x="99" y="-451"/>
</scene>
</scenes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination"/>
</simulatedMetricsContainer>
</document>

View File

@@ -0,0 +1,16 @@
//
// main.m
// SioChatDemo
//
// Created by Melo Yao on 3/30/15.
// Copyright (c) 2015 Melo Yao. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.socketio.melode.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -0,0 +1,40 @@
//
// SioChatDemoTests.m
// SioChatDemoTests
//
// Created by Melo Yao on 3/30/15.
// Copyright (c) 2015 Melo Yao. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
@interface SioChatDemoTests : XCTestCase
@end
@implementation SioChatDemoTests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
XCTAssert(YES, @"Pass");
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end

View File

@@ -0,0 +1,4 @@
ios/*
osx/*
src/*
boost_*

View File

@@ -0,0 +1,378 @@
#===============================================================================
# Filename: boost.sh
# Author: Pete Goodliffe
# Copyright: (c) Copyright 2009 Pete Goodliffe
# Licence: Please feel free to use this, with attribution
# Modified version
#===============================================================================
#
# Builds a Boost framework for the iPhone.
# Creates a set of universal libraries that can be used on an iPhone and in the
# iPhone simulator. Then creates a pseudo-framework to make using boost in Xcode
# less painful.
#
# To configure the script, define:
# BOOST_LIBS: which libraries to build
# IPHONE_SDKVERSION: iPhone SDK version (e.g. 5.1)
#
# Then go get the source tar.bz of the boost you want to build, shove it in the
# same directory as this script, and run "./boost.sh". Grab a cuppa. And voila.
#===============================================================================
: ${BOOST_LIBS:="random regex graph random chrono thread signals filesystem system date_time"}
: ${IPHONE_SDKVERSION:=`xcodebuild -showsdks | grep iphoneos | egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1`}
: ${OSX_SDKVERSION:=10.8}
: ${XCODE_ROOT:=`xcode-select -print-path`}
: ${EXTRA_CPPFLAGS:="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS -std=c++11 -stdlib=libc++"}
# The EXTRA_CPPFLAGS definition works around a thread race issue in
# shared_ptr. I encountered this historically and have not verified that
# the fix is no longer required. Without using the posix thread primitives
# an invalid compare-and-swap ARM instruction (non-thread-safe) was used for the
# shared_ptr use count causing nasty and subtle bugs.
#
# Should perhaps also consider/use instead: -BOOST_SP_USE_PTHREADS
: ${TARBALLDIR:=`pwd`}
: ${SRCDIR:=`pwd`/src}
: ${IOSBUILDDIR:=`pwd`/ios/build}
: ${OSXBUILDDIR:=`pwd`/osx/build}
: ${PREFIXDIR:=`pwd`/ios/prefix}
: ${IOSFRAMEWORKDIR:=`pwd`/ios/framework}
: ${OSXFRAMEWORKDIR:=`pwd`/osx/framework}
: ${COMPILER:="clang++"}
: ${BOOST_VERSION:=1.55.0}
: ${BOOST_VERSION2:=1_55_0}
BOOST_TARBALL=$TARBALLDIR/boost_$BOOST_VERSION2.tar.bz2
BOOST_SRC=$SRCDIR/boost_${BOOST_VERSION2}
#===============================================================================
ARM_DEV_CMD="xcrun --sdk iphoneos"
SIM_DEV_CMD="xcrun --sdk iphonesimulator"
OSX_DEV_CMD="xcrun --sdk macosx"
ARM_COMBINED_LIB=$IOSBUILDDIR/lib_boost_arm.a
SIM_COMBINED_LIB=$IOSBUILDDIR/lib_boost_x86.a
#===============================================================================
#===============================================================================
# Functions
#===============================================================================
abort()
{
echo
echo "Aborted: $@"
exit 1
}
doneSection()
{
echo
echo "================================================================="
echo "Done"
echo
}
#===============================================================================
cleanEverythingReadyToStart()
{
echo Cleaning everything before we start to build...
rm -rf iphone-build iphonesim-build osx-build
rm -rf $IOSBUILDDIR
rm -rf $OSXBUILDDIR
rm -rf $PREFIXDIR
rm -rf $IOSFRAMEWORKDIR/$FRAMEWORK_NAME.framework
rm -rf $OSXFRAMEWORKDIR/$FRAMEWORK_NAME.framework
doneSection
}
#===============================================================================
downloadBoost()
{
if [ ! -s $TARBALLDIR/boost_${BOOST_VERSION2}.tar.bz2 ]; then
echo "Downloading boost ${BOOST_VERSION}"
curl -L -o $TARBALLDIR/boost_${BOOST_VERSION2}.tar.bz2 http://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION2}.tar.bz2/download
fi
doneSection
}
#===============================================================================
unpackBoost()
{
[ -f "$BOOST_TARBALL" ] || abort "Source tarball missing."
echo Unpacking boost into $SRCDIR...
[ -d $SRCDIR ] || mkdir -p $SRCDIR
[ -d $BOOST_SRC ] || ( cd $SRCDIR; tar xfj $BOOST_TARBALL )
[ -d $BOOST_SRC ] && echo " ...unpacked as $BOOST_SRC"
doneSection
}
#===============================================================================
restoreBoost()
{
cp $BOOST_SRC/tools/build/v2/user-config.jam-bk $BOOST_SRC/tools/build/v2/user-config.jam
}
#===============================================================================
updateBoost()
{
echo Updating boost into $BOOST_SRC...
cp $BOOST_SRC/tools/build/v2/user-config.jam $BOOST_SRC/tools/build/v2/user-config.jam-bk
cat >> $BOOST_SRC/tools/build/v2/user-config.jam <<EOF
using darwin : ${IPHONE_SDKVERSION}~iphone
: $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch armv6 -arch armv7 -arch armv7s -arch arm64 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS
: <striper> <root>$XCODE_ROOT/Platforms/iPhoneOS.platform/Developer
: <architecture>arm <target-os>iphone
;
using darwin : ${IPHONE_SDKVERSION}~iphonesim
: $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch i386 -arch x86_64 -fvisibility=hidden -fvisibility-inlines-hidden $EXTRA_CPPFLAGS
: <striper> <root>$XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer
: <architecture>x86 <target-os>iphone
;
EOF
doneSection
}
#===============================================================================
inventMissingHeaders()
{
# These files are missing in the ARM iPhoneOS SDK, but they are in the simulator.
# They are supported on the device, so we copy them from x86 SDK to a staging area
# to use them on ARM, too.
echo Invent missing headers
cp $XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${IPHONE_SDKVERSION}.sdk/usr/include/{crt_externs,bzlib}.h $BOOST_SRC
}
#===============================================================================
bootstrapBoost()
{
cd $BOOST_SRC
BOOST_LIBS_COMMA=$(echo $BOOST_LIBS | sed -e "s/ /,/g")
echo "Bootstrapping (with libs $BOOST_LIBS_COMMA)"
./bootstrap.sh --with-libraries=$BOOST_LIBS_COMMA
doneSection
}
#===============================================================================
buildBoostForIPhoneOS()
{
cd $BOOST_SRC
# Install this one so we can copy the includes for the frameworks...
./bjam -j16 --build-dir=iphone-build --stagedir=iphone-build/stage --prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-${IPHONE_SDKVERSION} define=_LITTLE_ENDIAN link=static stage
./bjam -j16 --build-dir=iphone-build --stagedir=iphone-build/stage --prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-${IPHONE_SDKVERSION} define=_LITTLE_ENDIAN link=static install
doneSection
./bjam -j16 --build-dir=iphonesim-build --stagedir=iphonesim-build/stage --toolset=darwin-${IPHONE_SDKVERSION}~iphonesim architecture=x86 target-os=iphone macosx-version=iphonesim-${IPHONE_SDKVERSION} link=static stage
doneSection
# ./b2 -j16 --build-dir=osx-build --stagedir=osx-build/stage toolset=clang cxxflags="-std=c++11 -stdlib=libc++ -arch i386 -arch x86_64" linkflags="-stdlib=libc++" link=static threading=multi stage
doneSection
}
#===============================================================================
scrunchAllLibsTogetherInOneLibPerPlatform()
{
cd $BOOST_SRC
mkdir -p $IOSBUILDDIR/armv6/obj
mkdir -p $IOSBUILDDIR/armv7/obj
mkdir -p $IOSBUILDDIR/armv7s/obj
mkdir -p $IOSBUILDDIR/arm64/obj
mkdir -p $IOSBUILDDIR/i386/obj
mkdir -p $IOSBUILDDIR/x86_64/obj
mkdir -p $OSXBUILDDIR/i386/obj
mkdir -p $OSXBUILDDIR/x86_64/obj
ALL_LIBS=""
echo Splitting all existing fat binaries...
for NAME in $BOOST_LIBS; do
ALL_LIBS="$ALL_LIBS libboost_$NAME.a"
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv6 -o $IOSBUILDDIR/armv6/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv7 -o $IOSBUILDDIR/armv7/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin armv7s -o $IOSBUILDDIR/armv7s/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphone-build/stage/lib/libboost_$NAME.a" -thin arm64 -o $IOSBUILDDIR/arm64/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphonesim-build/stage/lib/libboost_$NAME.a" -thin i386 -o $IOSBUILDDIR/i386/libboost_$NAME.a
$ARM_DEV_CMD lipo "iphonesim-build/stage/lib/libboost_$NAME.a" -thin x86_64 -o $IOSBUILDDIR/x86_64/libboost_$NAME.a
$ARM_DEV_CMD lipo "osx-build/stage/lib/libboost_$NAME.a" -thin i386 -o $OSXBUILDDIR/i386/libboost_$NAME.a
$ARM_DEV_CMD lipo "osx-build/stage/lib/libboost_$NAME.a" -thin x86_64 -o $OSXBUILDDIR/x86_64/libboost_$NAME.a
done
echo "Decomposing each architecture's .a files"
for NAME in $ALL_LIBS; do
echo Decomposing $NAME...
(cd $IOSBUILDDIR/armv6/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/armv7/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/armv7s/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/arm64/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/i386/obj; ar -x ../$NAME );
(cd $IOSBUILDDIR/x86_64/obj; ar -x ../$NAME );
(cd $OSXBUILDDIR/i386/obj; ar -x ../$NAME );
(cd $OSXBUILDDIR/x86_64/obj; ar -x ../$NAME );
done
echo "Linking each architecture into an uberlib ($ALL_LIBS => libboost.a )"
rm $IOSBUILDDIR/*/libboost.a
echo ...armv6
(cd $IOSBUILDDIR/armv6; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...armv7
(cd $IOSBUILDDIR/armv7; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...armv7s
(cd $IOSBUILDDIR/armv7s; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...arm64
(cd $IOSBUILDDIR/arm64; $ARM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...i386
(cd $IOSBUILDDIR/i386; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...x86_64
(cd $IOSBUILDDIR/x86_64; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
rm $OSXBUILDDIR/*/libboost.a
echo ...osx-i386
(cd $OSXBUILDDIR/i386; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
echo ...x86_64
(cd $OSXBUILDDIR/x86_64; $SIM_DEV_CMD ar crus libboost.a obj/*.o; )
}
#===============================================================================
buildFramework()
{
: ${1:?}
FRAMEWORKDIR=$1
BUILDDIR=$2
VERSION_TYPE=Alpha
FRAMEWORK_NAME=boost
FRAMEWORK_VERSION=A
FRAMEWORK_CURRENT_VERSION=$BOOST_VERSION
FRAMEWORK_COMPATIBILITY_VERSION=$BOOST_VERSION
FRAMEWORK_BUNDLE=$FRAMEWORKDIR/$FRAMEWORK_NAME.framework
echo "Framework: Building $FRAMEWORK_BUNDLE from $BUILDDIR..."
rm -rf $FRAMEWORK_BUNDLE
echo "Framework: Setting up directories..."
mkdir -p $FRAMEWORK_BUNDLE
mkdir -p $FRAMEWORK_BUNDLE/Versions
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Resources
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Headers
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Documentation
echo "Framework: Creating symlinks..."
ln -s $FRAMEWORK_VERSION $FRAMEWORK_BUNDLE/Versions/Current
ln -s Versions/Current/Headers $FRAMEWORK_BUNDLE/Headers
ln -s Versions/Current/Resources $FRAMEWORK_BUNDLE/Resources
ln -s Versions/Current/Documentation $FRAMEWORK_BUNDLE/Documentation
ln -s Versions/Current/$FRAMEWORK_NAME $FRAMEWORK_BUNDLE/$FRAMEWORK_NAME
FRAMEWORK_INSTALL_NAME=$FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/$FRAMEWORK_NAME
echo "Lipoing library into $FRAMEWORK_INSTALL_NAME..."
$ARM_DEV_CMD lipo -create $BUILDDIR/*/libboost.a -o "$FRAMEWORK_INSTALL_NAME" || abort "Lipo $1 failed"
echo "Framework: Copying includes..."
cp -r $PREFIXDIR/include/boost/* $FRAMEWORK_BUNDLE/Headers/
echo "Framework: Creating plist..."
cat > $FRAMEWORK_BUNDLE/Resources/Info.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${FRAMEWORK_NAME}</string>
<key>CFBundleIdentifier</key>
<string>org.boost</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${FRAMEWORK_CURRENT_VERSION}</string>
</dict>
</plist>
EOF
doneSection
}
#===============================================================================
# Execution starts here
#===============================================================================
mkdir -p $IOSBUILDDIR
cleanEverythingReadyToStart #may want to comment if repeatedly running during dev
restoreBoost
echo "BOOST_VERSION: $BOOST_VERSION"
echo "BOOST_LIBS: $BOOST_LIBS"
echo "BOOST_SRC: $BOOST_SRC"
echo "IOSBUILDDIR: $IOSBUILDDIR"
echo "OSXBUILDDIR: $OSXBUILDDIR"
echo "PREFIXDIR: $PREFIXDIR"
echo "IOSFRAMEWORKDIR: $IOSFRAMEWORKDIR"
echo "OSXFRAMEWORKDIR: $OSXFRAMEWORKDIR"
echo "IPHONE_SDKVERSION: $IPHONE_SDKVERSION"
echo "XCODE_ROOT: $XCODE_ROOT"
echo "COMPILER: $COMPILER"
echo
downloadBoost
unpackBoost
inventMissingHeaders
bootstrapBoost
updateBoost
buildBoostForIPhoneOS
scrunchAllLibsTogetherInOneLibPerPlatform
buildFramework $IOSFRAMEWORKDIR $IOSBUILDDIR
buildFramework $OSXFRAMEWORKDIR $OSXBUILDDIR
restoreBoost
echo "Completed successfully"
#===============================================================================

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.socketio.melode.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>