我写了一个视图,搜索具有指定参数(用户名或角色)的元素。 请求将发送到Web api,后者返回结果用户的JSON数据。
以下是代码:
import UIKit
import Alamofire
class searchViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {
let headers = ["tb-token" : userToken!]
var loadedMode:Bool = false
var resultsN = 0
var resultsDict = NSArray()
//Outlets
@IBOutlet weak var wallpaper: UIImageView!
@IBOutlet weak var searchField: UITextField!
@IBOutlet weak var searchButton: UIButton!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var numberOfResults: UILabel!
//Search action
@IBAction func search(sender: AnyObject) {
let searchString = searchField.text//.lowercaseString
let trimmedString = searchString!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
if trimmedString.hasPrefix("@"){
let usernameString = trimmedString.stringByReplacingOccurrencesOfString("@", withString: "")
Alamofire.request(.GET, Constants.Path.rootUrl + "/api/users", parameters: ["username" : usernameString, "limit":3] , headers: ["tb-token" : userToken!])
.responseJSON { _, _, JSON in
print(JSON.value)
self.tableView.hidden = false
if JSON.isSuccess == true {
self.resultsDict = JSON.value as! NSArray
let results = JSON.value
let resultsNumber = results!.count
self.numberOfResults.text = "Results(\(resultsNumber))"
self.numberOfResults.hidden = false
self.resultsN = resultsNumber
self.loadedMode = true
self.tableView.reloadData()
} else { print("false") }
}
} else {
Alamofire.request(.GET, Constants.Path.rootUrl + "/api/users",parameters: ["role" : trimmedString, "limit" : 20], headers: ["tb-token" : userToken!])
.responseJSON { _, _, JSON in
print(JSON.value)
self.resultsDict = JSON.value as! NSArray
let results = JSON.value
let resultsNumber = results!.count
self.numberOfResults.text = "Results(\(resultsNumber))"
self.numberOfResults.hidden = false
self.resultsN = resultsNumber
self.loadedMode = true
self.tableView.reloadData()
self.tableView.hidden = false
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
//Setting the delegate for the results table
tableView.delegate = self
tableView.dataSource = self
//Setting the delegate for the search text field
searchField.delegate = self
//Adding the gesture recogniser to hide keyboard on tap
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
view.addGestureRecognizer(tap)
let theWidth = view.frame.size.width
let theHeight = view.frame.size.height
dispatch_async(dispatch_get_main_queue()){
self.wallpaper.frame = CGRectMake(0, 0, theWidth, theHeight)
self.wallpaper.alpha = 0.85
self.searchField.frame = CGRectMake(60, 70, theWidth-90, self.searchField.frame.height+7)
self.searchField.layer.borderColor = UIColor.blackColor().CGColor
self.view.addSubview(self.searchField)
self.searchButton.frame = CGRectMake(self.searchField.frame.minX+5 - self.searchField.frame.height, self.searchField.frame.minY-0.5, self.searchField.frame.height, self.searchField.frame.height+0.8)
self.view.addSubview(self.searchButton)
self.numberOfResults.frame = CGRectMake(25, self.searchField.frame.maxY + 20, 150, 30)
self.numberOfResults.textColor = UIColor.grayColor()
self.numberOfResults.hidden = true
self.tableView.frame = CGRectMake(0, self.searchField.frame.maxY + 50, theWidth, theHeight - self.searchField.frame.maxY - 40)
self.tableView.hidden = true
}
searchField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
searchField.addTarget(self, action: "textFieldDidChangeNow:", forControlEvents: UIControlEvents.EditingChanged)
}
func textFieldDidChangeNow(textField: UITextField) {
search(self)
}
//Tet changes color when searching for username
func textFieldDidChange(textField: UITextField) {
if textField.text!.hasPrefix("@") == true {
textField.textColor = UIColor.orangeColor()
} else {
textField.textColor = UIColor.blackColor()
}
}
//Hide keyboard on screen tap
func DismissKeyboard(){
view.endEditing(true)
}
//Hide keyboard when "Return" is pressed
func textFieldShouldReturn(textField: UITextField) -> Bool {
view.endEditing(true)
return false
}
//UITableView defaul functions
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if loadedMode == true {
return resultsN
} else {
return 1
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("searchResult") as! SearchResultTableViewCell
if loadedMode == false {
return cell
} else {
let username = resultsDict[indexPath.row].objectForKey("username") as! String
Alamofire.request(.GET, Constants.Path.rootUrl + "/api/users/?username=" + username + "&fields=image", headers: self.headers)
.responseJSON { _,_, JSON in
let array = JSON.value?.objectAtIndex(0) as! NSDictionary
let imageString = array.objectForKey("image") as! String
let imageUrl = NSURL(string: imageString)
//cell.profilePic.sd_setImageWithURL(imageUrl)
dispatch_async(dispatch_get_main_queue()) {
let imageData = UIImage(data: NSData(contentsOfURL: imageUrl!)!)
cell.profilePic.image = imageData?.circleMask
cell.profilePic.frame.size.width = 70
cell.profilePic.frame.size.height = 70
cell.profilePic.layer.cornerRadius = cell.profilePic.frame.width/2
cell.profilePic.layer.masksToBounds = true
cell.profilePic.clipsToBounds = true
cell.username.frame = CGRectMake(cell.profilePic.frame.maxX+5, cell.profilePic.frame.minY, 120, 20)
cell.role.frame = CGRectMake(cell.profilePic.frame.maxX+5, cell.username.frame.maxY+7, 180, 20)
cell.username.text = self.resultsDict[indexPath.row].objectForKey("name") as? String
cell.role.text = self.resultsDict[indexPath.row].objectForKey("role") as? String
}
}
return cell
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
}
但是,我认为我搞砸了后台任务,所以我遇到了这样的错误:
Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (3) beyond bounds (3)
*** First throw call stack:
(
0 CoreFoundation 0x0000000111aebf65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000111565deb objc_exception_throw + 48
2 CoreFoundation 0x0000000111aebe9d +[NSException raise:format:] + 205
3 CoreFoundation 0x0000000111a0cb63 -[__NSCFArray objectAtIndex:] + 163
4 TeamBuilding No Parse 0x000000010fd0471d _TFFFC21TeamBuilding_No_Parse20searchViewController9tableViewFS0_FTCSo11UITableView21cellForRowAtIndexPathCSo11NSIndexPath_CSo15UITableViewCellU_FTGSqCSo12NSURLRequest_GSqCSo17NSHTTPURLResponse_GO9Alamofire6ResultPSs9AnyObject___T_U_FT_T_ + 4349
5 TeamBuilding No Parse 0x000000010fccc9e7 _TTRXFo__dT__XFdCb__dT__ + 39
6 libdispatch.dylib 0x00000001148f7ef9 _dispatch_call_block_and_release + 12
7 libdispatch.dylib 0x000000011491849b _dispatch_client_callout + 8
8 libdispatch.dylib 0x000000011490034b _dispatch_main_queue_callback_4CF + 1738
9 CoreFoundation 0x0000000111a4c3e9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
10 CoreFoundation 0x0000000111a0d939 __CFRunLoopRun + 2073
11 CoreFoundation 0x0000000111a0ce98 CFRunLoopRunSpecific + 488
12 GraphicsServices 0x0000000117acaad2 GSEventRunModal + 161
13 UIKit 0x0000000112797676 UIApplicationMain + 171
14 TeamBuilding No Parse 0x000000010fd2b91d main + 109
15 libdyld.dylib 0x000000011494c92d start + 1
16 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
有人可以识别我的代码中的问题吗?谢谢!