用c#开发苹果应用程序 xamarin.ios方式
Networkcomms网络通信框架来自于英国,支持以xamarin.ios的方式开发苹果应用程序
其开源版本2.3.1中带有一个示例程序,实现聊天功能,只要输入对方手机的IP和端口就能够显示聊天,可以作为学习networkcomms框架的入门程序
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using NetworkCommsDotNet;
namespace ExamplesChat.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
public override UIWindow Window
{
get;
set;
}
/// <summary>
/// If the application is minimised we need to correctly shutdown NetworkComms.Net
/// </summary>
/// <param name="application"></param>
public override void DidEnterBackground(UIApplication application)
{
NetworkComms.Shutdown();
}
}
}
AppDelegate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetworkCommsDotNet;
using DPSBase;
namespace ExamplesChat.iOS
{
/// <summary>
/// In an attempt to keep things as clear as possible all shared implementation across chat examples
/// has been provided in this base class.
/// </summary>
public abstract class ChatAppBase
{
#region Private Fields
/// <summary>
/// A boolean used to track the very first initialisation
/// </summary>
protected bool FirstInitialisation { get; set; }
/// <summary>
/// Dictionary to keep track of which peer messages have already been written to the chat window
/// </summary>
protected Dictionary<ShortGuid, ChatMessage> lastPeerMessageDict = new Dictionary<ShortGuid, ChatMessage>();
/// <summary>
/// The maximum number of times a chat message will be relayed
/// </summary>
;
/// <summary>
/// A local counter used to track the number of messages sent from
/// this instance.
/// </summary>
;
/// <summary>
/// An optional encryption key to use should one be required.
/// This can be changed freely but must obviously be the same
/// for both sender and reciever.
/// </summary>
string _encryptionKey = "ljlhjf8uyfln23490jf;m21-=scm20--iflmk;";
#endregion
#region Public Fields
/// <summary>
/// The type of connection currently used to send and recieve messages. Default is TCP.
/// </summary>
public ConnectionType ConnectionType { get; set; }
/// <summary>
/// The IP address of the server
/// </summary>
public string ServerIPAddress { get; set; }
/// <summary>
/// The port of the server
/// </summary>
public int ServerPort { get; set; }
/// <summary>
/// The local name used when sending messages
/// </summary>
public string LocalName { get; set; }
/// <summary>
/// A boolean used to track if the local device is acting as a server
/// </summary>
public bool LocalServerEnabled { get; set; }
/// <summary>
/// A boolean used to track if encryption is currently being used
/// </summary>
public bool EncryptionEnabled { get; set; }
#endregion
/// <summary>
/// Constructor for ChatAppBase
/// </summary>
public ChatAppBase(string name, ConnectionType connectionType)
{
LocalName = name;
ConnectionType = connectionType;
//Initialise the default values
ServerIPAddress = "";
ServerPort = ;
LocalServerEnabled = false;
EncryptionEnabled = false;
FirstInitialisation = true;
}
#region NetworkComms.Net Methods
/// <summary>
/// Updates the configuration of this instance depending on set fields
/// </summary>
public void RefreshNetworkCommsConfiguration()
{
#region First Initialisation
//On first initilisation we need to configure NetworkComms.Net to handle our incoming packet types
//We only need to add the packet handlers once. If we call NetworkComms.Shutdown() at some future point these are not removed.
if (FirstInitialisation)
{
FirstInitialisation = false;
//Configure NetworkComms.Net to handle any incoming packet of type 'ChatMessage'
//e.g. If we recieve a packet of type 'ChatMessage' execute the method 'HandleIncomingChatMessage'
NetworkComms.AppendGlobalIncomingPacketHandler<ChatMessage>("ChatMessage", HandleIncomingChatMessage);
//Configure NetworkComms.Net to perform some action when a connection is closed
//e.g. When a connection is closed execute the method 'HandleConnectionClosed'
NetworkComms.AppendGlobalConnectionCloseHandler(HandleConnectionClosed);
}
#endregion
#region Optional Encryption
//Configure encryption if requested
if (EncryptionEnabled && !NetworkComms.DefaultSendReceiveOptions.DataProcessors.Contains(DPSBase.DPSManager.GetDataProcessor<DPSBase.RijndaelPSKEncrypter>()))
{
//Encryption is currently implemented using a pre-shared key (PSK) system
//NetworkComms.Net supports multiple data processors which can be used with any level of granularity
//To enable encryption globally (i.e. for all connections) we first add the encryption password as an option
DPSBase.RijndaelPSKEncrypter.AddPasswordToOptions(NetworkComms.DefaultSendReceiveOptions.Options, _encryptionKey);
//Finally we add the RijndaelPSKEncrypter data processor to the sendReceiveOptions
NetworkComms.DefaultSendReceiveOptions.DataProcessors.Add(DPSBase.DPSManager.GetDataProcessor<DPSBase.RijndaelPSKEncrypter>());
}
else if (!EncryptionEnabled && NetworkComms.DefaultSendReceiveOptions.DataProcessors.Contains(DPSBase.DPSManager.GetDataProcessor<DPSBase.RijndaelPSKEncrypter>()))
{
//If encryption has been disabled but is currently enabled
//To disable encryption we just remove the RijndaelPSKEncrypter data processor from the sendReceiveOptions
NetworkComms.DefaultSendReceiveOptions.DataProcessors.Remove(DPSBase.DPSManager.GetDataProcessor<DPSBase.RijndaelPSKEncrypter>());
}
#endregion
#region Local Server Mode and Connection Type Changes
if (LocalServerEnabled && ConnectionType == ConnectionType.TCP && !TCPConnection.Listening())
{
//If we were previously listening for UDP we first shutdown comms.
if (UDPConnection.Listening())
{
AppendLineToChatHistory("Connection mode has been changed. Any existing connections will be closed.");
NetworkComms.Shutdown();
}
else
{
AppendLineToChatHistory("Enabling local server mode. Any existing connections will be closed.");
NetworkComms.Shutdown();
}
//Start listening for new incoming TCP connections
//Parameter is true so that we listen on a random port if the default is not available
TCPConnection.StartListening(true);
//Write the IP addresses and ports that we are listening on to the chatBox
AppendLineToChatHistory("Listening for incoming TCP connections on:");
foreach (var listenEndPoint in TCPConnection.ExistingLocalListenEndPoints())
AppendLineToChatHistory(listenEndPoint.Address + ":" + listenEndPoint.Port);
//Add a blank line after the initialisation output
AppendLineToChatHistory(System.Environment.NewLine);
}
else if (LocalServerEnabled && ConnectionType == ConnectionType.UDP && !UDPConnection.Listening())
{
//If we were previously listening for TCP we first shutdown comms.
if (TCPConnection.Listening())
{
AppendLineToChatHistory("Connection mode has been changed. Any existing connections will be closed.");
NetworkComms.Shutdown();
}
else
{
AppendLineToChatHistory("Enabling local server mode. Any existing connections will be closed.");
NetworkComms.Shutdown();
}
//Start listening for new incoming UDP connections
//Parameter is true so that we listen on a random port if the default is not available
UDPConnection.StartListening(true);
//Write the IP addresses and ports that we are listening on to the chatBox
AppendLineToChatHistory("Listening for incoming UDP connections on:");
foreach (var listenEndPoint in UDPConnection.ExistingLocalListenEndPoints())
AppendLineToChatHistory(listenEndPoint.Address + ":" + listenEndPoint.Port);
//Add a blank line after the initialisation output
AppendLineToChatHistory(System.Environment.NewLine);
}
else if (!LocalServerEnabled && (TCPConnection.Listening() || UDPConnection.Listening()))
{
//If the local server mode has been disabled but we are still listening we need to stop accepting incoming connections
NetworkComms.Shutdown();
AppendLineToChatHistory("Local server mode disabled. Any existing connections will be closed.");
AppendLineToChatHistory(System.Environment.NewLine);
}
else if (!LocalServerEnabled &&
((ConnectionType == ConnectionType.UDP && NetworkComms.GetExistingConnection(ConnectionType.TCP).Count > ) ||
(ConnectionType == ConnectionType.TCP && NetworkComms.GetExistingConnection(ConnectionType.UDP).Count > )))
{
//If we are not running a local server but have changed the connection type after creating connections we need to close
//existing connections.
NetworkComms.Shutdown();
AppendLineToChatHistory("Connection mode has been changed. Existing connections will be closed.");
AppendLineToChatHistory(System.Environment.NewLine);
}
#endregion
}
/// <summary>
/// Performs whatever functions we might so desire when we recieve an incoming ChatMessage
/// </summary>
/// <param name="header">The PacketHeader corresponding with the recieved object</param>
/// <param name="connection">The Connection from which this object was recieved</param>
/// <param name="incomingMessage">The incoming ChatMessage we are after</param>
protected virtual void HandleIncomingChatMessage(PacketHeader header, Connection connection, ChatMessage incomingMessage)
{
//We only want to write a message once to the chat window
//Because we support relaying and may recieve the same message twice from multiple sources
//we use our history and message indexes to ensure we have a new message
//We perform this action within a lock as HandleIncomingChatMessage could be called in parallel
lock (lastPeerMessageDict)
{
if (lastPeerMessageDict.ContainsKey(incomingMessage.SourceIdentifier))
{
if (lastPeerMessageDict[incomingMessage.SourceIdentifier].MessageIndex < incomingMessage.MessageIndex)
{
//If this message index is greater than the last seen from this source we can safely
//write the message to the ChatBox
AppendLineToChatHistory(incomingMessage.SourceName + " - " + incomingMessage.Message);
//We now replace the last recieved message with the current one
lastPeerMessageDict[incomingMessage.SourceIdentifier] = incomingMessage;
}
}
else
{
//If we have never had a message from this source before then it has to be new
//by defintion
lastPeerMessageDict.Add(incomingMessage.SourceIdentifier, incomingMessage);
AppendLineToChatHistory(incomingMessage.SourceName + " - " + incomingMessage.Message);
}
}
//This last section of the method is the relay feature
//We start by checking to see if this message has already been relayed the maximum number of times
if (incomingMessage.RelayCount < relayMaximum)
{
//If we are going to relay this message we need an array of
//all known connections, excluding the current one
var allRelayConnections = (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();
//We increment the relay count before we send
incomingMessage.IncrementRelayCount();
//We now send the message to every other connection
foreach (var relayConnection in allRelayConnections)
{
//We ensure we perform the send within a try catch
//To ensure a single failed send will not prevent the
//relay to all working connections.
try { relayConnection.SendObject("ChatMessage", incomingMessage); }
catch (CommsException) { /* Catch the comms exception, ignore and continue */ }
}
}
}
/// <summary>
/// Performs whatever functions we might so desire when an existing connection is closed.
/// </summary>
/// <param name="connection">The closed connection</param>
private void HandleConnectionClosed(Connection connection)
{
//We are going to write a message to the chat history when a connection disconnects
//We perform the following within a lock incase mutliple connections disconnect simultaneously
lock (lastPeerMessageDict)
{
//Get the remoteIdentifier from the closed connection
//This a unique GUID which can be used to identify peers
ShortGuid remoteIdentifier = connection.ConnectionInfo.NetworkIdentifier;
//If at any point we recieved a message with a matching identifier we can
//include the peer name in the disconnection message.
if (lastPeerMessageDict.ContainsKey(remoteIdentifier))
AppendLineToChatHistory("Connection with '" + lastPeerMessageDict[remoteIdentifier].SourceName + "' has been closed.");
else
AppendLineToChatHistory("Connection with '" + connection.ToString() + "' has been closed.");
//Last thing is to remove this peer from our message history
lastPeerMessageDict.Remove(connection.ConnectionInfo.NetworkIdentifier);
}
}
/// <summary>
/// Send a message.
/// </summary>
public void SendMessage(string stringToSend)
{
//If we have tried to send a zero length string we just return
if (stringToSend.Trim() == "") return;
//We may or may not have entered some server connection information
ConnectionInfo serverConnectionInfo = null;
if (ServerIPAddress != "")
{
try { serverConnectionInfo = new ConnectionInfo(ServerIPAddress, ServerPort); }
catch (Exception)
{
ShowMessage("Failed to parse the server IP and port. Please ensure it is correct and try again");
return;
}
}
//We wrap everything we want to send in the ChatMessage class we created
ChatMessage chatMessage = new ChatMessage(NetworkComms.NetworkIdentifier, LocalName, stringToSend, messageSendIndex++);
//We add our own message to the message history incase it gets relayed back to us
lock (lastPeerMessageDict) lastPeerMessageDict[NetworkComms.NetworkIdentifier] = chatMessage;
//We write our own message to the chatBox
AppendLineToChatHistory(chatMessage.SourceName + " - " + chatMessage.Message);
//Clear the input box text
ClearInputLine();
//If we provided server information we send to the server first
if (serverConnectionInfo != null)
{
//We perform the send within a try catch to ensure the application continues to run if there is a problem.
try
{
if (ConnectionType == ConnectionType.TCP)
TCPConnection.GetConnection(serverConnectionInfo).SendObject("ChatMessage", chatMessage);
else if (ConnectionType == ConnectionType.UDP)
UDPConnection.GetConnection(serverConnectionInfo, UDPOptions.None).SendObject("ChatMessage", chatMessage);
else
throw new Exception("An invalid connectionType is set.");
}
catch (CommsException) { AppendLineToChatHistory("Error: A communication error occured while trying to send message to " + serverConnectionInfo + ". Please check settings and try again."); }
catch (Exception) { AppendLineToChatHistory("Error: A general error occured while trying to send message to " + serverConnectionInfo + ". Please check settings and try again."); }
}
//If we have any other connections we now send the message to those as well
//This ensures that if we are the server everyone who is connected to us gets our message
//We want a list of all established connections not including the server if set
List<ConnectionInfo> otherConnectionInfos;
if (serverConnectionInfo != null)
otherConnectionInfos = (from current in NetworkComms.AllConnectionInfo() where current.RemoteEndPoint != serverConnectionInfo.RemoteEndPoint select current).ToList();
else
otherConnectionInfos = NetworkComms.AllConnectionInfo();
foreach (ConnectionInfo info in otherConnectionInfos)
{
//We perform the send within a try catch to ensure the application continues to run if there is a problem.
try
{
if (ConnectionType == ConnectionType.TCP)
TCPConnection.GetConnection(info).SendObject("ChatMessage", chatMessage);
else if (ConnectionType == ConnectionType.UDP)
UDPConnection.GetConnection(info, UDPOptions.None).SendObject("ChatMessage", chatMessage);
else
throw new Exception("An invalid connectionType is set.");
}
catch (CommsException) { AppendLineToChatHistory("Error: A communication error occured while trying to send message to " + info + ". Please check settings and try again."); }
catch (Exception) { AppendLineToChatHistory("Error: A general error occured while trying to send message to " + info + ". Please check settings and try again."); }
}
return;
}
#endregion
#region GUI Interface Methods
/// <summary>
/// Outputs the usage instructions to the chat window
/// </summary>
public void PrintUsageInstructions()
{
AppendLineToChatHistory("");
AppendLineToChatHistory("Chat usage instructions:");
AppendLineToChatHistory("");
AppendLineToChatHistory("Step 1. Open atleast two chat applications. You can choose from Android, Windows Phone, iOS or native Windows versions.");
AppendLineToChatHistory("Step 2. Enable local server mode in a single application, see settings.");
AppendLineToChatHistory("Step 3. Provide remote server IP and port information in settings on remaining application.");
AppendLineToChatHistory("Step 4. Start chatting.");
AppendLineToChatHistory("");
AppendLineToChatHistory("Note: Connections are established on the first message send.");
AppendLineToChatHistory("");
}
/// <summary>
/// Append the provided message to the chat history text box.
/// </summary>
/// <param name="message">Message to be appended</param>
public abstract void AppendLineToChatHistory(string message);
/// <summary>
/// Clears the chat history
/// </summary>
public abstract void ClearChatHistory();
/// <summary>
/// Clears the input text box
/// </summary>
public abstract void ClearInputLine();
/// <summary>
/// Show a message box as an alternative to writing to the chat history
/// </summary>
/// <param name="message">Message to be output</param>
public abstract void ShowMessage(string message);
#endregion
}
}
ChatAppBase
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using NetworkCommsDotNet;
namespace ExamplesChat.iOS
{
/// <summary>
/// All NetworkComms.Net implementation can be found here and in ChatAppBase
/// </summary>
public class ChatAppiOS : ChatAppBase
{
#region Public Fields
/// <summary>
/// Size of the chat history view when the keyboard is hidden
/// </summary>
, , , );
/// <summary>
/// Reference to the chatHistory text view.
/// </summary>
public UITextView ChatHistoryBox { get; private set; }
/// <summary>
/// Reference to the message box.
/// </summary>
public UITextField MessageBox { get; private set; }
#endregion
/// <summary>
/// Constructor for the iOS chat app.
/// </summary>
public ChatAppiOS(UITextView chatHistoryBox, UITextField messageBox)
: base("iPhone", ConnectionType.TCP)
{
ChatHistoryBox = chatHistoryBox;
MessageBox = messageBox;
}
#region GUI Interface Overrides
public override void AppendLineToChatHistory(string message)
{
ChatHistoryBox.InvokeOnMainThread(new NSAction(() =>
{
ChatHistoryBox.Text += message + Environment.NewLine;
PointF bottomOffset = , ChatHistoryBox.ContentSize.Height - ChatHistoryBox.Bounds.Size.Height);
ChatHistoryBox.SetContentOffset(bottomOffset, true);
}));
}
public override void ClearChatHistory()
{
ChatHistoryBox.InvokeOnMainThread(new NSAction(() =>
{
ChatHistoryBox.Text = "";
PointF bottomOffset = , ChatHistoryBox.ContentSize.Height - ChatHistoryBox.Bounds.Size.Height);
ChatHistoryBox.SetContentOffset(bottomOffset, true);
}));
}
public override void ClearInputLine()
{
MessageBox.InvokeOnMainThread(new NSAction(() =>
{
MessageBox.Text = "";
}));
}
public override void ShowMessage(string message)
{
throw new NotImplementedException();
}
#endregion
}
}
ChatAppiOS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//We need to add the following two namespaces to this class
using NetworkCommsDotNet;
using ProtoBuf;
namespace ExamplesChat.iOS
{
/// <summary>
/// A wrapper class for the messages that we intend to send and recieve.
/// The [ProtoContract] attribute informs NetworkCommsDotNet that we intend to
/// serialise (turn into bytes) this object. At the base level the
/// serialisation is performed by protobuf.net.
/// </summary>
[ProtoContract]
public class ChatMessage
{
/// <summary>
/// The source identifier of this ChatMessage.
/// We use this variable as the constructor for the ShortGuid.
/// The [ProtoMember(1)] attribute informs the serialiser that when
/// an object of type ChatMessage is serialised we want to include this variable
/// </summary>
[ProtoMember()]
string _sourceIdentifier;
/// <summary>
/// The source identifier is accessible as a ShortGuid
/// </summary>
public ShortGuid SourceIdentifier { get { return new ShortGuid(_sourceIdentifier); } }
/// <summary>
/// The name of the source of this ChatMessage.
/// We use shorthand declaration, get and set.
/// The [ProtoMember(2)] attribute informs the serialiser that when
/// an object of type ChatMessage is serialised we want to include this variable
/// </summary>
[ProtoMember()]
public string SourceName { get; private set; }
/// <summary>
/// The actual message.
/// </summary>
[ProtoMember()]
public string Message { get; private set; }
/// <summary>
/// The index of this message. Every message sent by a particular source
/// has an incrementing index.
/// </summary>
[ProtoMember()]
public long MessageIndex { get; private set; }
/// <summary>
/// The number of times this message has been relayed.
/// </summary>
[ProtoMember()]
public int RelayCount { get; private set; }
/// <summary>
/// We must include a public parameterless constructor to be used by the deserialisation step.
/// </summary>
public ChatMessage() { }
/// <summary>
/// Create a new ChatMessage
/// </summary>
/// <param name="sourceIdentifier">The source identifier</param>
/// <param name="sourceName">The source name</param>
/// <param name="message">The message to be sent</param>
/// <param name="messageIndex">The index of this message</param>
public ChatMessage(ShortGuid sourceIdentifier, string sourceName, string message, long messageIndex)
{
this._sourceIdentifier = sourceIdentifier;
this.SourceName = sourceName;
this.Message = message;
this.MessageIndex = messageIndex;
;
}
/// <summary>
/// Increment the relay count variable
/// </summary>
public void IncrementRelayCount()
{
RelayCount++;
}
}
}
ChatMessage
// This file has been autogenerated from parsing an Objective-C header file added in Xcode.
using System;
using System.Linq;
using System.Net;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using NetworkCommsDotNet;
using DPSBase;
namespace ExamplesChat.iOS
{
public partial class ChatWindow : UIViewController
{
public static ChatAppiOS ChatApplication { get; set; }
public ChatWindow (IntPtr handle) : base (handle)
{
}
/// <summary>
/// On load initialise the example
/// </summary>
public override void ViewDidLoad()
{
base.ViewDidLoad();
//Subscribe to the keyboard events
NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.DidHideNotification, HandleKeyboardDidHide);
NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.DidShowNotification, HandleKeyboardDidShow);
//Remove the keyboard if the screen is tapped
var tap = new UITapGestureRecognizer();
tap.AddTarget(() =>
{
this.View.EndEditing(true);
});
this.View.AddGestureRecognizer(tap);
//Create the chat application instance
ChatApplication = new ChatAppiOS(ChatHistory, MessageBox);
//Uncomment this line to enable logging
//EnableLogging();
//Print out the application usage instructions
ChatApplication.PrintUsageInstructions();
//Initialise comms to add the neccessary packet handlers
ChatApplication.RefreshNetworkCommsConfiguration();
}
/// <summary>
/// Enable logging, usefull for debugging applications.
/// </summary>
private void EnableLogging()
{
//We will create the log file in the local documents directory
string logFileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "NetworkCommsLog.txt");
ChatApplication.AppendLineToChatHistory("Logging enabled to " + logFileName);
NetworkComms.EnableLogging(logFileName);
}
#region Event Handlers
/// <summary>
/// Sends the message when send button is clicked
/// </summary>
/// <param name="sender"></param>
partial void SendButtonClick(NSObject sender)
{
ChatApplication.SendMessage(MessageBox.Text);
}
/// <summary>
/// Resize the view to take into account the keyboard position
/// </summary>
/// <param name="notification"></param>
void HandleKeyboardDidShow(NSNotification notification)
{
ChatApplication.ClearInputLine();
NSObject value = notification.UserInfo[UIKeyboard.FrameEndUserInfoKey];
RectangleF keyboardFrame = ((NSValue)value).RectangleFValue;
ChatView.Frame = new System.Drawing.RectangleF(ChatView.Frame.X, ChatView.Frame.Y, ChatView.Frame.Width, ChatView.Frame.Height - keyboardFrame.Height);
PointF bottomOffset = , ChatHistory.ContentSize.Height - ChatHistory.Bounds.Size.Height);
ChatHistory.SetContentOffset(bottomOffset, true);
}
/// <summary>
/// Resize the view once the keyboard has been minimised
/// </summary>
/// <param name="notification"></param>
private void HandleKeyboardDidHide(NSNotification notification)
{
//Set back to original size
ChatView.Frame = ChatApplication.OriginalViewSize;
}
#endregion
}
}
ChatWindow
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace ExamplesChat.iOS
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}
Application
// This file has been autogenerated from parsing an Objective-C header file added in Xcode.
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using NetworkCommsDotNet;
namespace ExamplesChat.iOS
{
public partial class Settings : UIViewController
{
public Settings (IntPtr handle) : base (handle)
{
}
/// <summary>
/// On load set the config as per the chat application
/// </summary>
public override void ViewDidLoad()
{
base.ViewDidLoad();
//Remove the keyboard on a tap gesture
var tap = new UITapGestureRecognizer();
tap.AddTarget(() =>
{
this.View.EndEditing(true);
});
this.View.AddGestureRecognizer(tap);
//Get a reference to the chat application
ChatAppiOS chatApplication = ChatWindow.ChatApplication;
//Update the settings based on previous values
LocalServerEnabled.SetState(chatApplication.LocalServerEnabled, false);
MasterIP.Text = chatApplication.ServerIPAddress;
MasterPort.Text = chatApplication.ServerPort.ToString();
LocalName.Text = chatApplication.LocalName;
EncryptionEnabled.SetState(chatApplication.EncryptionEnabled, false);
//Set the correct segment on the connection mode toggle
ConnectionMode.SelectedSegment = (chatApplication.ConnectionType == ConnectionType.TCP ? : );
}
/// <summary>
/// Update the settings when the user goes back to the main interface
/// </summary>
/// <returns></returns>
public override bool ResignFirstResponder()
{
//Get a reference to the chat application
ChatAppiOS chatApplication = ChatWindow.ChatApplication;
//Parse settings and store back in chat application
chatApplication.ServerIPAddress = MasterIP.Text.Trim();
;
int.TryParse(MasterPort.Text, out port);
chatApplication.ServerPort = port;
chatApplication.LocalName = LocalName.Text.Trim();
chatApplication.EncryptionEnabled = EncryptionEnabled.On;
chatApplication.LocalServerEnabled = LocalServerEnabled.On;
)
chatApplication.ConnectionType = ConnectionType.TCP;
else
chatApplication.ConnectionType = ConnectionType.UDP;
//Refresh the NetworkComms.Net configuration once any changes have been made
chatApplication.RefreshNetworkCommsConfiguration();
return base.ResignFirstResponder();
}
}
}
Settings
工程文件下载地址 networkcomm2.3.1开源通信框架下载网页
www.networkcomms.cn
用c#开发苹果应用程序 xamarin.ios方式的更多相关文章
- 【转】如何开发苹果iOS操作平台下的应用程序?
原文网址:http://zhidao.baidu.com/link?url=vxRWjCchSstFmVKvxEqLqfqomu2h5kF-NLAIVEehQgN_FnYtEi4f5yPMS6ywbU ...
- Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序
Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序 C#原本是用来编写Windows以及Windows Phone的应用程序.自从Xamarin问世后.C#的作用就发生了非常大的变化 ...
- 【Xamarin挖墙脚系列:Xamarin.IOS的程序的结构】
原文:[Xamarin挖墙脚系列:Xamarin.IOS的程序的结构] 开始熟悉Xamarin在开发IOS的结构!!!!!!! 先看官方 这个是以一个单页面的程序进行讲述的. 1 程序引用的程序集,核 ...
- Xamarin.iOS开发初体验
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0
- Xamarin iOS编写第一个应用程序创建工程
Xamarin iOS编写第一个应用程序创建工程 在Xcode以及Xamarin安装好后,就可以在Xamarin Studio中编写程序了.本节将主要讲解在Xamarin Studio中如何进行工程的 ...
- iOS Simulator功能介绍关于Xamarin IOS开发
iOS Simulator功能介绍关于Xamarin IOS开发 iOS Simulator功能介绍 在图1.38所示的运行效果中,所见到的类似于手机的模型就是iOS Simulator.在没有iPh ...
- Xamarin iOS开发中的编辑、连接、运行
Xamarin iOS开发中的编辑.连接.运行 创建好工程后,就可以单击Xamarin Studio上方的运行按钮,如图1.37所示,对HelloWorld项目进行编辑.连接以及运行了.运行效果如图1 ...
- Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍
原文 Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍 前言 在上一篇文章中, 我们介绍了Xamarin 以及简单的HelloWorld范例, 这次我们针对iO ...
- 使用Xamarin开发手机聊天程序 -- 基础篇(大量图文讲解 step by step,附源码下载)
如果是.NET开发人员,想学习手机应用开发(Android和iOS),Xamarin 无疑是最好的选择,编写一次,即可发布到Android和iOS平台,真是利器中的利器啊!而且,Xamarin已经被微 ...
随机推荐
- iOS - OC 内存管理
1.OC 基本内存管理模型 1.1 自动垃圾收集 在 OC 2.0 中,有一种称为垃圾收集的内存管理形式.通过垃圾收集,系统能够自动监测对象是否拥有其他的对象,当程序执行需要空间的时候,不再被引用的对 ...
- c++ primer 的 textquery 例子。
总共3种方法,一种是第四版书上的面向对象的教学方法.一种是实际中应该使用的简洁方法.一种是模板的方法. 1)第四版书中,面向对象的方法,基类,继承,多态 2)自己的更简洁的写法.(前提条件:如果不需要 ...
- retire or not retire ? is a question.
corejava 上的一段代码 因吹思婷 "C:\Program Files\Java\jdk1.8.0_101\bin\java" -Didea.launcher.port=75 ...
- QQMain
import java.awt.*; import javax.swing.*; import java.awt.event.*; public class QQMain extends JFrame ...
- mysql 内连接 左连接 右连接 外连接
mysql> desc student;+-------+-------------+------+-----+---------+-------+| Field | Type | Null | ...
- Android 四种简单的动画(淡入淡出、旋转、移动、缩放效果)
最近在Android开发当中,用到的动画效果. public void onClick(View arg0) { // TODO 自动生成的方法存根 switch (arg0.getId()) { c ...
- Python学习笔记5-元组
元组是用圆括号括起来的,其中的元素之间用逗号隔开 >>> t = 123,'abc',["come","here"] >>> ...
- 关于jQuery的小知识点
jQuery 简介 jQuery 库可以通过一行简单的标记被添加到网页中. jQuery 库 - 特性 jQuery 是一个 JavaScript 函数库. jQuery 库包含以下特性: HTML ...
- 屏幕输出VS文件输出
问题1:我们在编写程序时经常需要数一些数据到屏幕,来查看我们的结果是否正确,虽然直接输出到屏幕,查看起来呢很方便,但当数据量很大时,需要耗费大量的时间.于是我们想到能不能通过输出到文件来减少时间 ...
- Jquery如何获得<iframe>嵌套页面中的元素
DOM方法:父窗口操作IFRAME:window.frames["iframeSon"].documentIFRAME操作父窗口: window.parent.documentjq ...