2015年1月29日 星期四

閉包 Closures - 高階函式 Higher-order functions

func connect(str1 : String, str2 : String) -> String {
    return str1 + " " + str2
}
connect("hello","world") // "hello world"

func say(name : String, function : (String, String) -> String) -> String{
    let greet = "你好"
    var str = function(name, greet)
    return str
}

// 1. 函數被當成變數傳入另一個函數
var result = say("Ian",connect)
println(result) // "Ian 你好"

// 2. 閉包運算式(Closure Expressions
// connect函數的名稱用函數型態取代,in關鍵字之後為程式碼內容。
result = say("Peter", { (str1:String, str2:String) -> String in
    return str1 + " " + str2
})
println(result) // "Peter 你好"

// 3. 根據上下文推斷型態(Inferring Type From Context
result = say("Alex", { str1, str2 in
    return str1 + " " + str2
})
println(result)// "Alex 你好"

// 4. 閉包單行表示式隱含返回(Implicit Return From Single-Expression Clossures
// 拿掉return關鍵字
result = say("Jay", { str1, str2 in str1 + " " + str2 })
println(result) // "Jay 你好"

// 5. 參數名稱縮寫(Shorthand Argument Names
// 直接通過$0,$1,$2...來順序引用閉包的參數
result = say("Alice", { $0 + " " + $1 })
println(result) // "Alice 你好"

// 6. 運算符函數(Operator Functions
// 簡單地傳遞一個加號,Swift可以自動推斷出我們想使用加號的字串函數操作。
result = say("Bob", + )
println(result) // "Bob 你好"

// 尾隨閉包(Trailing Closures
// 把最後一個參數(閉包函數)搬出參數列括弧,整個大括弧搬出小括弧之外。當閉包內容冗長的時候,適合這樣表達。
result = say("Tim"){
    (str1 : String, str2 : String) -> String in return str1 + str2
}
println(result) // "Tim 你好"
======================================

使用 Javascript 的範例,改寫成 Swift 版
http://ianworkshop.blogspot.tw/2014/03/blog-post.html

高階函示 : 
1. 把其他函式當作引數 (callback function / 回呼函式, 即呼叫時傳入她, 然後她再呼叫回來)
2. 會回傳函式

  • 使用標準程式庫原本的方法


// 將陣列中的數值由小到大重新排列
var nums = [1,3,5,7,9,8,6,4,2]

// 2. 閉包運算式
nums.sort({ (n1:Int, n2:Int) -> Bool in
    n1 < n2
})
println(nums)

// 3. 推斷型態
nums.sort({ n1, n2 in
    return n1 < n2
})

// 4. 隱含返回 (拿掉return關鍵字)
nums.sort({ n1, n2 in n1 < n2 })

// 5. 參數名稱縮寫
nums.sort({ $0 < $1 })

// 6. 運算符函數
nums.sort( < )

// 7. 尾隨閉包
nums.sort{ (n1:Int, n2:Int) -> Bool in
    n1 < n2
}

// 尾隨閉包 + 參數名稱縮寫

nums.sort{ $0 < $1 }

======
// 將陣列中的字串都轉為大寫
var names = ["Ian","Peter","Kevin"]
// 尾隨閉包 + 參數名稱縮寫

names = names.map { $0.uppercaseString }
println(names) // "[IAN, PETER, KEVIN]"



  • 自訂高階函式
// 依照條件建立字串
func builderString(n:Int, callback:(counting:Int) -> String ) -> String {
    var result = "";
    for i in 0...n {
        result = result + callback(counting: i)
    }
    return result
}

// 建立 1~9
var digits_1 = builderString(8, { (counting) -> String in
    return "\(counting+1)"
})

var digits_2 = builderString(8) { "\($0+1)"}

2015年1月21日 星期三

Status Bar

Xcode 6.1.1

這一個是 Status Bar


隱藏:

在專案下的 General > Deployment Info 有一個選項 Hide status bar,打勾後啟動專案發現並沒有消失,所以這個功能沒有作用。

到 Navigator 下找到在 Supporting Files 資料夾裡的 Info.plist,click 右鍵 > Open As > Source Code,在 <dict> 裡面加入:
    <key>UIViewControllerBasedStatusBarAppearance</key>

    <false/>
再次執行專案就看不到 Status Bar 了,對 Info.plist 點擊右鍵 > Open As > Property List,可以看到多了一個 key-value pair:



也可以直接在 Property List 中加入

改變顏色:

在狀態列是開啟的情況時,如果在白色背景下將某個 View 的 Status Bar 設為亮色系,也有隱藏效果
    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return .LightContent
    }
如果將背景改為黑色,則顯示如圖所示:









2015年1月19日 星期一

AJAX 與 [Authorize]


ASP.NET MVC 在 Controller 或 Action 上加上 [Authorize] 就可以驗證是否已經登入,如果沒有登入就會被帶往登入頁面

當使用ajax方式則會得到狀態為200的頁面(指定的頁面),因此需要改寫可以回傳一個Json :

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new JsonResult
            {
                Data = new 
                { 
                    // put whatever data you want which will be sent
                    // to the client
                    message = "sorry, but you were logged out" 
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

$.get('@Url.Action("SomeAction")', function (result) {
    if (result.message) {
        alert(result.message);
    } else {
        // do whatever you were doing before with the results
    }
});
如果是用 AngularJs,IsAjaxRequest 會一直判斷是 false,因為 AngularJs 的 ajax 呼叫沒有包含 X-Requested-With 表頭,而 ASP.NET MVC 是用這個表來判斷是否為一個 ajax 呼叫,所以必須改為:

var productsApp = angular.module('productsApp', []);
productsApp.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest'
}]);