Showing posts with label network. Show all posts
Showing posts with label network. Show all posts

Friday, July 3, 2015

RSNetworking 2

I would like to announce the release of RSNetworking 2 for Swift 2.  RSNetworking 2 has all the same great features that RSNetworking has but it was written to work with Swift 2.  RSNetworking and RSNetworking 2 are network libraries written entirely in the Swift programming language.  You can find RSNetworking 2 here:  https://github.com/hoffmanjon/RSNetworking2

Below lists the API that is exposed with RSNetworking 2

Classes
This section lists the classes that make up the RSNetworking API

RSTransaction
RSTransaction is the class that defines the transaction we wish to make. It exposes four properties, one initiator and one method.

Properties
  •   TransactionType - This defines the HTTP request method. Currently there are three types, GET, POST, UNKNOWN. Only the GET and POST actually sends a request. 
  •   baseURL - This is the base URL to use for the request. This will normally look something like this: "https://itunes.apple.com". If you are going to a non-standard port you would put that here as well. It will look something like this: "http://mytestserver:8080" 
  •   path - The path that will be added to the base url. This will normally be something like this: "search". It can also include a longer path string like: "path/to/my/service" 
  •   parameters - Any parameters to send to the service.

Initiators
  •   init(transactionType: RSTransactionType, baseURL: String, path: String, parameters: [String: String]) - This will initialize the RSTransaction with all properties needed.

Functions
  •   getFullURLString() -> String - Builds and returns the full URL needed to connect to the service.

RSTransactionRequest
RSTransactionRequest is the class that builds and sends out the request to the service defined by the RSTransaction. It exposes four functions.

Functions
  •   dataFromRSTransaction(transaction: RSTransaction, completionHandler handler: RSNetworking.dataFromRSTransactionCompletionCompletionClosure): Retrieves an NSData object from the service defined by the RSTransaction. This is the main function and is used by the other three functions to retrieve an NSData object prior to converting it to the required format.
  •   stringFromRSTransaction(transaction: RSTransaction, completionHandler handler: RSNetworking.stringFromRSTransactionCompletionCompletionClosure): Retrieves an NSString object from the service defined by the RSTransaction. This function uses the dataFromRSTransaction function to retrieve an NSData object and then converts it to an NSString object.
  •   dictionaryFromRSTransaction(transaction: RSTransaction, completionHandler handler: RSNetworking.dictionaryFromRSTransactionCompletionCompletionClosure): Retrieves an NSDictionary object from the service defined by the RSTransaction. This function uses the dataFromRSTransaction function to retrieve an NSData object and then converts it to an NSDictionary object. The data returned from the URL should be in JSON format for this function to work properly.
  •   imageFromRSTransaction(transaction: RSTransaction, completionHandler handler: RSNetworking.imageFromRSTransactionCompletionCompletionClosure): Retrieves an UIImage object from the service defined by the RSTransaction. This function uses the dataFromRSTransaction function to retrieve an NSData object and then converts it to an UIImage object.

RSURLRequest
RSURLRequest will send a GET request to a service with just a URL. There is no need to define a RSTransaction to use this class. RSURLRequest exposes four functions.

Functions
  •   dataFromURL(url: NSURL, completionHandler handler: RSNetworking.dataFromURLCompletionClosure): Retrieves an NSData object from the URL passed in. This is the main function and is used by the other three functions to retrieve an NSData object prior to converting it to the required format
  •   stringFromURL(url: NSURL, completionHandler handler: RSNetworking.stringFromURLCompletionClosure): Retrieves an NSString object from the URL passed in. This function uses the dataFromURL function to retrieve an NSData object and then converts it to an NSString object.
  •   dictionaryFromJsonURL(url: NSURL, completionHandler handler: RSNetworking.dictionaryFromURLCompletionClosure): Retrieves an NSDictionary object from the URL passed in. This function uses the dataFromURL function to retrieve an NSData object and then converts it to an NSDictionary object. The data returned from the URL should be in JSON format for this function to work properly.
  •   imageFromURL(url: NSURL, completionHandler handler: RSNetworking.imageFromURLCompletionClosure): Retrieves an UIImage object from the URL. This function uses the dataFromURL function to retrieve an NSData object and then converts it to an UIImage object.

RSUtilities
RSUtilities will contain various utilities that do not have their own class. Currently there is only one function exposed by this class

Functions
  •   isNetworkAvailable(hostname: NSString) -> Bool - This function will check to see if the network is available. This is a class function.
  •   networkConnectionType(hostname: NSString) -> ConnectionType - This function will return the type of network connection that is available. The ConnectionType is an enum which can equal one of the following three types: NONETWORK, MOBILE3GNETWORK or WIFINETWORK.

Extensions
This section lists the extensions that RSNetworking adds to the Swift language

UIImageView
  •     setImageForURL(url: NSString, placeHolder: UIImage): Sets the image in the UIImageView to the placeHolder image and then asynchronously downloads the image from the URL. Once the image downloads it will replace the placeholder image with the downloaded image.
  •     setImageForURL(url: NSString): Asynchronously downloads the image from the URL. Once the image is downloaded, it sets the image of the UIImageView to the downloaded image.
  •     setImageForRSTransaction(transaction:RSTransaction, placeHolder: UIImage): Sets the image in the UIImageView to the placeHolder image and then asynchronously downloads the image from the RSTransaction. Once the image downloads it will replace the placeholder image with the downloaded image.
  •     setImageForRSTransaction(transaction:RSTransaction): Asynchronously downloads the image from the RSTransaction. Once the image downloads it sets the image of the UIImageView to the downloaded image.
UIButton  
  •     setButtonImageForURL(url: NSString, placeHolder: UIImage, state: UIControlState): Sets the background image of the UIButton to the placeholder image and then asynchronously downloads the image from the URL. Once the image downloads it will replace the placeHolder image with the downloaded image.
  •     setButtonImageForURL(url: NSString, state: UIControlState): Asynchronously downloads the image from the URL. Once the download is complete, it will set the background image of the UIButton to the downloaded image.
  •     setButtonImageForRSTransaction(transaction:RSTransaction, placeHolder: UIImage, state: UIControlState): Sets the background image of the UIButton to the placeHolder image and then asynchronously downloads the image from the URL. Once the image downloads it will replace the placeHolder image with the downloaded image.
  •     setButtonImageForRSTransaction(transaction:RSTransaction, state: UIControlState): Asynchronously downloads the image from the URL. Once the download is complete, it will set the background image of the UIButton to the downloaded image.

Sample Code
This section contains sample code that show how to use RSNetworking

RSURLRequest
dataFromURL
let client = RSURLRequest()

if let testURL = NSURL(string:"https://itunes.apple.com/search?term=jimmy+buffett&media=music") {

   client.dataFromURL(testURL, completionHandler: {(response : NSURLResponse!, responseData: NSData!, error: NSError!) -> Void in
      if let error = error {
          print("Error : \(error)")
      } else {
          let string = NSString(data: responseData, encoding: NSUTF8StringEncoding)
          print("Response Data: \(string)")
      }
   }) 
}

dictionaryFromJsonURL
let client = RSURLRequest()

if let testURL = NSURL(string:"https://itunes.apple.com/search?term=jimmy+buffett&media=music") {

  client.dictionaryFromJsonURL(testURL, completionHandler: {(response : NSURLResponse!, responseDictionary: NSDictionary!, error: NSError!) -> Void in
      if let error = error {
          print("Error : \(error)")
      } else {
          print("Response Dictionary: \(responseDictionary)")
      }
   })
}

stringFromURL
let client = RSURLRequest()

if let testURL = NSURL(string:"https://itunes.apple.com/search?term=jimmy+buffett&media=music") {

  client.stringFromURL(testURL, completionHandler: {(response : NSURLResponse!, responseString: NSString!, error: NSError!) -> Void in
      if let error = error {
          print("Error : \(error)")
      } else {
          print("Response Data: \(responseString)")
      }
   })
}

imageFromURL
let client = RSURLRequest()

if let imageURL = NSURL(string:"http://a1.mzstatic.com/us/r30/Music/y2003/m12/d17/h16/s05.whogqrwc.100x100-75.jpg") {

  client.imageFromURL(imageURL, completionHandler: {(response : NSURLResponse!, image: UIImage!, error: NSError!) -> Void in
      if let error = error {
          print("Error : \(error)")
      } else {
          self.imageView?.image = image;
      }
   })
}

RSUtilities
RSUtilities.isHostnameReachable
  if (RSUtilities.isNetworkAvailable("www.apple.com")) {
     print("reachable")
 } else {
     print("Not Reachable")
 }

UIImageView: setImageForURL
let imageURL = "http://a1.mzstatic.com/us/r30/Music/y2003/m12/d17/h16/s05.whogqrwc.100x100-75.jpg"
  
imageView.setImageForURL(imageURL, placeHolder: UIImage(named: "loading"))    

  or

let imageURL = "http://a1.mzstatic.com/us/r30/Music/y2003/m12/d17/h16/s05.whogqrwc.100x100-75.jpg"

self.imageView?.setImageForURL(imageURL)

UIButton: setImageForURL
let imageURL = "http://a1.mzstatic.com/us/r30/Music/y2003/m12/d17/h16/s05.whogqrwc.100x100-75.jpg"

button.setButtonImageForURL(url, placeHolder: UIImage(named: "loading"), state:.Normal)

  or

let imageURL = "http://a1.mzstatic.com/us/r30/Music/y2003/m12/d17/h16/s05.whogqrwc.100x100-75.jpg"

button.setButtonImageForURL(url, state:.Normal)

RSTransactionRequest
RSTransactionRequest is designed to be used when you need to create mulitple requests to the same service. It allows you to set up the request once and then just change the parameters for each request

dictionaryFromRSTransaction
let rsRequest = RSTransactionRequest()

//Create the initial request
let rsTransGet = RSTransaction(transactionType: RSTransactionType.GET, baseURL: "https://itunes.apple.com", path: "search", parameters: ["term":"jimmy+buffett","media":"music"])

rsRequest.dictionaryFromRSTransaction(rsTransGet, completionHandler: {(response : NSURLResponse!, responseDictionary: NSDictionary!, error: NSError!) -> Void in
    if let error = error {
        print("Error : \(error)")
    } else {
        print(responseDictionary)
    }
})


Now that you have the RSTransaction, you can simply change the parameters and make another request, if needed, like this:
  
let rsRequest = RSTransactionRequest()

//Create the initial request
rsTransGet.parameters = ["term":"Jimmy", "media":"music"]

rsRequest.dictionaryFromRSTransaction(rsTransGet, completionHandler: {(response : NSURLResponse!, responseDictionary: NSDictionary!, error: NSError!) -> Void in
    if let error = error {
        print("Error : \(error)")
    } else {
        print(responseDictionary)
    }
})

stringFromRSTransaction
  
//Change parameters from the previously example so we can make a second request
rsTransGet.parameters = ["term":"Jimmy", "media":"music"]
rsRequest.stringFromRSTransaction(rsTransGet, completionHandler: {(response : NSURLResponse!, responseString: NSString!, error: NSError!) -> Void in
    if let error = error {
        print("Error : \(error)")
    } else {
        print(responseString)
    }
})


If there is a feature that you would like to see in RSNetworking 2, please leave a comment to this blog post or in the github site here:  https://github.com/hoffmanjon/RSNetworking2.  If you would like to contribute to RSNetworking 2, please feel free to do so. 

Wednesday, July 16, 2014

RSNetworking – A network library written in Swift: Update 1


A few days ago I wrote about a network library that I am writing in Swift, you can see the post here.  Tonight I committed my first update to the library.  This update adds an extension to the UIImageView class and a function to check if a host is reachable.  The GitHub repository is here:  https://github.com/hoffmanjon/RSNetworking

The UIImageView extensions adds two functions to asynchronously download an image from a URL.   These functions are:
  • setImageForURL(url: NSString, placeHolder: UIImage):  Sets the image in the UIImageView to the placeHolder image and then asynchronously downloads the image from the URL.  Once the image is downloaded it then replaces the placeHolder image with the image downloaded.
  • setImageForURL(url: NSString):  Asynchronously downloads the image from the URL.  Once the image is downloaded, it sets the image of the UIImageView to the downloaded image. 

I also added a function to check if a host is reachable or not.  This function is:

  • isHostReachable(hostname: NSString) -> Bool:  Returns true if the host is reachable or false if it is not.

A second sample project was added that shows how to use the UIImageView extension and the isHostReachable function.

I will hopefully be able to update this library on a regular basis.  If anyone would like to contribute to the library, please do so.  Also any suggestions on what you would like to see in the library would also be helpful. 

Sunday, February 2, 2014

Layers of the Internet Protocol Suite


As we begin to discuss network development it is essential that you have a good understanding of how the layers in the Internet Protocol Suite work. This knowledge is required to use packet capture libraries like libpcap or packet construction libraries like libnet but it is also very useful when troubleshooting your applications.
This post will, hopefully, give you a good introduction of how the layers work together but to really understand the layers you will need to spend time looking at and dissecting packets. Wireshark is an excellent tool to look at what packets are going though your network but it is a lot more fun to write your own packet-capturing tool with libpcap. My book, iOS and OS X Network Programming Cookbook, has a chapter on libpcap and shows how to write a packet capturing application for OS X. I also plan on posting tutorials on libpcap in this blog.
So what are the layers of the Internet Protocol suite and why should you care about them? When computers on an IP network, like the Internet, want to communicate they exchange packets. These packets contain two types of information, which are:
Control Information (header): This header provides the information needed to route, assemble and verify the packet.
User Data (payload): This is the data which is more commonly referred to as the payload. This can be anything from web pages to PDF files to streaming video.
A packet contains several headers that are layered. These layers are:

Link Layer: There are many types of network connections. The link layer defines the method in which the hosts communicate over the network. This can also be referred to as the Physical layer.
Internet Layer: The Internet layer defines the addressing and routing structures used. There are two versions of addressing structure these are IPv4 and IPv6.
Protocol (transport) Layer: The protocol layer (Commonly referred to as the Transport layer) provides a uniform networking interface that hides the underlying network connections. This is also where larger payloads are broken up into multiple packets if needed.
Application Layer: The application layer is where high-level protocols such as HTTP and FTP reside. This is usually where the payload that is being sent to the other application or device is added.

The biggest strength of this model is that each layer is independent and does not rely on the layers below it. For example, the Application Layer does not need to know anything about how the Link Layer is going to handle the packet.

When a packet is built each layer wraps (or encapsulates) the layer above it. Therefore the Protocol Layer encapsulates the Application Layer. The Internet Layer encapsulates the Protocol Layer which has already encapsulated the Application Layer. Finally the Link Layer encapsulates the Internet Layer which has already encapsulated the Protocol Layer which has already encapsulated the Application Layer.

When a packet is received the headers are peeled away in reverse order. Once the device receives the packet the Link Layer header is removed and the packet is passed up to the Internet Layer. The IP header is then removed and the packet is passed up to the Protocol Layer. Finally the protocol header is removed and the packet is then passed to the application. A picture below shows the order that a packet is built and peeled apart.