[文章]简单用Swift封装了下HTTP请求

使用尽量简化,调用时两行解决

    let request = SMWebRequest(url: "http://example.com", parameters: ["page_index":"1","page_size":"10"])
    request.requestWithCompletion{data,error in
    var result = NSString(data: data, encoding: NSUTF8StringEncoding)
            println(result)
    }

完整实现如下

//
//  SMWebRequest.swift
//  lab
//
//  Created by ming on 14-7-17.
//  Copyright (c) 2014年 starming. All rights reserved.
//

import Foundation

var _requestQueue: NSOperationQueue?

class SMWebRequest:NSObject,NSURLConnectionDataDelegate {
    typealias SMWebRequestCompletionHandler = (NSData?,NSError?)->Void
    var url: String
    var parameters: Dictionary<String, String> = Dictionary()
    var requestType: String
    var completionHandler: SMWebRequestCompletionHandler
    var receivedData = NSData()
    var connection: NSURLConnection?
    
    init(url:String, parameters:Dictionary<String, String>, requestType:String="post") {
        self.url = url
        self.parameters = parameters
        self.requestType = requestType
        completionHandler = {data,error in}
        super.init()
    }
    
    func requestWithCompletion(completionHandler:SMWebRequestCompletionHandler) {
        self.completionHandler = completionHandler
        requesting()
    }
    
    func requesting() {
        let request:NSMutableURLRequest = NSMutableURLRequest(URL: NSURL.URLWithString(url))
        let postDict = parameters
        
        var result = ""
        var firstPass = true
        for (key,value) in postDict {
            let encodedKey:String = key.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
            let encodedValue:String = value.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
            result += firstPass ? "(encodedKey)=(encodedValue)" : "&(encodedKey)=(encodedValue)"
            firstPass = false
        }
        let postData = result.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
        
        var httpMethod = "POST"
        if (requestType == "post") {
        }
        if (requestType == "get"){
            httpMethod = "GET"
            url += "&" + result
        }
        
        request.HTTPMethod = httpMethod
        request.HTTPBody = postData
        
        var postDataString = ""
        if let validBody = postData {
            if (validBody.length > 0) {
                postDataString = String(validBody.length)
            }
        }
        
        var header = [
            "Content-Type" : "application/x-www-form-urlencoded",
            "Content-Length" : postDataString
        ]
        for (key,value)in header {
            request.setValue(value, forHTTPHeaderField: key)
        }
        
        //Queue
        if _requestQueue == nil {
            _requestQueue = NSOperationQueue()
            _requestQueue!.maxConcurrentOperationCount = 4
            _requestQueue!.name = "com.starming.SMWebRequest"
        }
        
        connection = NSURLConnection(request: request, delegate: self)
        connection!.setDelegateQueue(_requestQueue)
        connection!.start()
    }
    
    //NSURLConnectionDataDelegate
    func connection(connection: NSURLConnection!, didFailWithError error: NSError!) {
        completionHandler(nil,error)
    }
    
    func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
        
    }
    
    func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
        receivedData = data;
    }
    
    func connectionDidFinishLoading(connection: NSURLConnection!) {
        completionHandler(receivedData,nil)
    }
    
}

[文章]在Playground里把Swift读薄

用下面的代码来替代swift手册吧 来自github:https://github.com/hackswift/swift-reference-pg

// Swift Reference PlayGround

import Cocoa

// Basic Print Statement
println("Hello, world")

/// Variables and Constants ----------------------------------
var myVariable = 42
myVariable = 50 // Can be reassigned
let myConstant = 42 // Cannot be reassigned

// Automatic Type Inference
let implicitInteger = 70
let implicitDouble = 70.0

// Explicit Type Definition
let explicitDouble: Double = 70
let testConst :Float = 4

// Avoid divide by zero, returns 0 when second parameter is zero
10 &/ 5
10 &/ 0

// Type Casting
let label = "The width is "
let width = 94
let widthLabel = label + String(width)

// Formating String
let apples = 3
let oranges = 5
let appleSummary = "I have (apples) apples."
let fruitSummary = "I have (apples + oranges) pieces of fruit."

let floatTest = "Float Addition :(4 + 5.0)"

// Arrays
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"

// Dictionary
var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]

occupations["Jayne"] = "Public Relations"

// Empty Array and Dictionary
var emptyArray = [String]()
var emptyDictionary = Dictionary<String, Float>()

// Type inferred
emptyArray = []
emptyDictionary = [:]

/// Control Flow ------------------------------------------

// Optional Values - only optional values can be nil.
var optionalString: String?
optionalString == nil
// Non optional values needs to be initialized before using them. So they don't need explicit nil checks.
var string: String = "Test String"
string == "Test String"

// if
var optionalName: String?
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, (name)"
}
optionalName = "John Appleseed"
if let name = optionalName {
    greeting = "Hello, (name)"
}

// switch
let vegetable = "red pepper"
switch vegetable {
case "celery":
    let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
    let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
    let vegetableComment = "Is it a spicy (x)?"
default:
    let vegetableComment = "Everything tastes good in soup."
}

// for-in
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
teamScore

// Nested for-in
let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25],
]
var largest = 0
var largestKind = ""
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
            largestKind = kind
        }
    }
}
largest
largestKind

// while, do-while
var n = 2
while n < 100 {
    n = n * 2
}
n

var m = 2
do {
    m = m * 2
} while m < 100
m

// Range in loops
var firstForLoop = 0
for i in 0..<3 {
    firstForLoop += i
}
firstForLoop

var thirdForLoop = 0
for i in 0...2 {
    thirdForLoop += i
}
thirdForLoop

var secondForLoop = 0
for var i = 0; i < 3; ++i {
    secondForLoop += 1
}
secondForLoop

/// Functions and Closures ---------------------------------------------

func greet(name: String, day: String) -> String {
    return "Hello (name), today is (day)."
}
greet("Bob", "Tuesday")

// Multiple return values - Tuples
func getGasPrices() -> (Double, Double, Double) {
    return (3.59, 3.69, 3.79)
}
getGasPrices()

// Variable number of args
func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}
sumOf()
sumOf(42, 597, 12)

// Nested Functions
func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()

// Return functions
func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

// Functions as arguments
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen)

// Closures

numbers.map({
    (number: Int) -> Int in
    if number%2 != 0 {
        return 0
    } else {
        let result = 3 * number
        return result
    }
    })

// Inline closures
numbers.map({
    number in 3 * number
    })

// Very Short Closures
//sort([1, 5, 3, 12, 2]) { $0 > $1 }

/// Objects and Classes ---------------------------------------------

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with (numberOfSides) sides."
    }
}

// Access properties and methods
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

// init / constructor
class NamedShape {
    var numberOfSides: Int = 0
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func simpleDescription() -> String {
        return "A shape with (numberOfSides) sides."
    }
}

// Super Classes and Method overriding
class Square: NamedShape {
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }
    
    func area() ->  Double {
        return sideLength * sideLength
    }
    
    override func simpleDescription() -> String {
        return "A square with sides of length (sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

// Getters and Setters
class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }
    
    var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
    }
    
    override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length (sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

// willSet and didSet - Will be executed before and after setter respectively
class TriangleAndSquare {
    var triangle: EquilateralTriangle {
    willSet {
        square.sideLength = newValue.sideLength
    }
    }
    var square: Square {
    willSet {
        triangle.sideLength = newValue.sideLength
    }
    }
    init(size: Double, name: String) {
        square = Square(sideLength: size, name: name)
        triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
triangleAndSquare.square.sideLength
triangleAndSquare.triangle.sideLength
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
triangleAndSquare.triangle.sideLength

// Parameter names in methods inside classes
class Counter {
    var count: Int = 0
    func incrementBy(amount: Int, numberOfTimes times: Int) {
        count += amount * times
    }
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)

// Null / Nil Check
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength

/// Enumerations and Structures ----------------------------------------
enum Rank: Int {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
        case .Ace:
            return "ace"
        case .Jack:
            return "jack"
        case .Queen:
            return "queen"
        case .King:
            return "king"
        default:
            return String(self.toRaw())
        }
    }
}
let card = Rank.Jack
let aceRawValue = card.simpleDescription()

if let convertedRank = Rank.fromRaw(13) {
    let threeDescription = convertedRank.simpleDescription()
}

// Enums without Raw types
enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() -> String {
        switch self {
        case .Spades:
            return "spades"
        case .Hearts:
            return "hearts"
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        }
    }
    func color() -> String {
        switch self {
        case .Spades, .Clubs:
            return "black"
        case .Hearts, .Diamonds:
            return "red"
        }
    }
}
let hearts = Suit.Hearts
let heartsDescription = hearts.simpleDescription()
hearts.color()

// Structs
struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The (rank.simpleDescription()) of (suit.simpleDescription())"
    }
}

let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

// Enumeration with Values
enum ServerResponse {
    case Result(String, String)
    case Error(String)
}

let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")

switch success {
case let .Result(sunrise, sunset):
    let serverResponse = "Sunrise is at (sunrise) and sunset is at (sunset)."
case let .Error(error):
    let serverResponse = "Failure...  (error)"
}

/// Protocols and Extensions -----------------------------------------
protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += "  Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

// Extensions
extension Int: ExampleProtocol {
    var simpleDescription: String {
    return "The number (self)"
    }
    mutating func adjust() {
        self += 42
    }
}
7.simpleDescription

// Referencing by Protocol

let protocolValue: ExampleProtocol = a
protocolValue.simpleDescription
// protocolValue.anotherProperty  // Uncomment to see the error

/// Generics -------------------------------------------------------
func repeat<ItemType>(item: ItemType, times: Int) -> [ItemType] {
    var result = [ItemType]()
    for i in 0..<times {
        result += item
    }
    return result
}
repeat("knock", 4)

// Generic Enums
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)

// Generics with restrictions
func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                return true
            }
        }
    }
    return false
}
anyCommonElements([1, 2, 3], [3])

// Infix Operator

operator infix =~ {}

func =~ (input: String, search: String) -> Bool {
    return input.rangeOfString(search) ? true : false
}

"iPhone" =~ "Phone"



[移动应用]“已阅”上架后提交到了GitHub

GitHub地址:https://github.com/ming1016/RSSRead

以下是项目README.md 的内容

RSSRead

“已阅”是一个iOS设备上的RSS/Atom阅读器。

已有主要功能

  • Add a new feed with powerful search
  • Offline feed read
  • Star the content you like
  • Mark as read and mark all as read
  • 能够删除管理已添加rss源
  • 文章分享功能

TODO

  • 期待同好一起完善
  • 关联Twitter内容和Weibo内容
  • feedly等rss服务的接口处理
  • InoReader的api处理,可在设置里加入第三方帐号绑定功能
  • UI设计优化
  • 分享到微信,微博等
  • coredata需要组织一下
  • 整理RSS推荐源,添加RSS时可以进行分类选择

项目主要贡献者

ID|Github Page -|- ming1016|https://github.com/ming1016 zaczh|https://github.com/zaczh wuzhou|https://github.com/wuzhou ftxbird|https://github.com/ftxbird ben46|https://github.com/ben46

参与进来

太好了,即使你不是开发者也有你能够贡献的,你可以做

本地化
  • English
  • Japanese
  • Simplified Chinese
策划
  • 阅读软件重度用户即可
写代码

联系我

“已阅”已在App Store上架

https://itunes.apple.com/us/app/yi-yue-rss-li-xian-xin-wen-yue-du/id850246364?ls=1&mt=8

主要使用的技术

Licensing

  • RSSRead is available under the MIT license.