I am trying to display a Json result (temperature and Humidity) on my view controller (respectively temperatureDisp and humidityDisp), but it does not seem to work.
class HomeVC: UIViewController {
#IBOutlet var usernameLabel: UILabel!
#IBOutlet var temperatureDisp: UILabel!
#IBOutlet var humidityDisp: UILabel!
#IBAction func logoutTapped(sender: AnyObject) {
let appDomain = NSBundle.mainBundle().bundleIdentifier
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain!)
self.performSegueWithIdentifier("goto_login", sender: self)
}
override func viewDidAppear(animated: Bool) {
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let isLoggedIn:Int = prefs.integerForKey("ISLOGGEDIN") as Int
if (isLoggedIn != 1) {
self.performSegueWithIdentifier("goto_login", sender: self)
} else {
self.usernameLabel.text = prefs.valueForKey("USERNAME") as! NSString as String
}
}
override func viewDidLoad() {
super.viewDidLoad()
var url2 : String = "http://admin:xxxxxxx#xxxxxx/xxxxx.fr/metrics2.php"
var request2 : NSMutableURLRequest = NSMutableURLRequest()
request2.URL = NSURL(string: url2)
request2.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request2, queue: NSOperationQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult : NSArray! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: error) as! NSArray
if (jsonResult != nil) {
println(jsonResult)
} else {
println("There is a problem")
}
var temperature = jsonResult[0].valueForKey("temperature") as! String
var humidity = jsonResult[0].valueForKey("humidite") as! String
println(temperature)
println(humidity)
self.humidityDisp.text = temperature
})
}
}}
That is how the variable jsonResult looks :
(
{
Id = 117;
date = "2015-04-06";
humidite = "45.3";
login = raspberrypi;
luminosite = "\U00e9teinte";
temperature = "18.4";
time = "16:25:21";
}
)
I'm not sure what you mean by "it does not seem to work", but from your code I can assume at least that you are not getting the values you expect from your JSON result, but more likely your app is crashing like crazy. If you want to write applications in Swift you absolutely must understand optionals and learn how to properly work with them. Read The Swift Programming Languageāand thoroughly. As your code is now, by force unwrapping using as! and using implicitly unwrapped types (those followed by !) you are ignoring the entire concept of optionals and opening yourself up to crashes.
So, assuming that there is no network or parsing errors, and assuming that the JSON string you're parsing has an array as its root object, the following should work. I've taken the liberty of typing and unwrapping your variables appropriately, as well as cleaning up some of the cruft.
class HomeVC: UIViewController {
#IBOutlet var usernameLabel: UILabel!
#IBOutlet var temperatureDisp: UILabel!
#IBOutlet var humidityDisp: UILabel!
#IBAction func logoutTapped(sender: AnyObject) {
if let appDomain = NSBundle.mainBundle().bundleIdentifier {
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)
}
self.performSegueWithIdentifier("goto_login", sender: self)
}
override func viewDidAppear(animated: Bool) {
let prefs = NSUserDefaults.standardUserDefaults()
let isLoggedIn = prefs.boolForKey("ISLOGGEDIN")
if isLoggedIn {
self.performSegueWithIdentifier("goto_login", sender: self)
} else {
if let username = prefs.stringForKey("USERNAME") {
self.usernameLabel.text = username
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
var url2 = "http://admin:xxxxxxx#xxxxxx/xxxxx.fr/metrics2.php"
var request2 = NSMutableURLRequest()
request2.URL = NSURL(string: url2)
request2.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request2, queue: NSOperationQueue()) { (response: NSURLResponse!,data: NSData!,error: NSError!) in
var parseError:NSError?
if let data = data, let jsonResults = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &parseError) as? NSArray {
println( jsonResults )
if let result = jsonResults.firstObject as? [String : AnyObject] {
if let humidity = result["humidite"] as? String {
self.humidityDisp.text = humidity
}
if let temperature = result["temperature"] as? String {
self.temperatureDisp.text = temperature
}
}
} else {
println("There is a problem: \(parseError)" )
}
}
}
}
Related
I have run into a problem where I can save and load into and from CoreData in Swift for my iOS app, but I run into a problem where I have tried to guard for duplicate entries, but it does not seem to work. can anyone tell me where I went wrong? Thanks!
My ViewController class:
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDelegate,
UITableViewDataSource {
#IBOutlet weak var headerLabel:UILabel!
#IBOutlet weak var myTableView: UITableView!
var lenders = [LenderData]()
var lendersTemp = [LenderData]()
override func viewDidLoad() {
super.viewDidLoad()
self.myTableView.rowHeight = 90
myTableView.delegate = self
myTableView.dataSource = self
let fetchRequest: NSFetchRequest<LenderData> = LenderData.fetchRequest()
do {
let lenders = try PersistenceService.context.fetch(fetchRequest)
self.lenders = lenders
} catch {
// Who cares....
}
downloadJSON {
for tempLender in self.lendersTemp {
if !self.lenders.contains(where: {$0.id == tempLender.id}) {
self.lenders.append(tempLender)
}
}
self.lendersTemp.removeAll()
PersistenceService.saveContext()
self.myTableView.reloadData()
}
}
func downloadJSON(completed: #escaping () -> ()) {
let url = URL(string: "https://api.kivaws.org/v1/loans/newest.json")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("JSON not downloaded")
} else {
if let content = data {
do {
let myJSONData = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
var imageID:Int64 = -1
var country:String = "N/A"
var latLongPair:String = "0.000000 0.000000"
var town:String = "N/A"
if let loans = myJSONData["loans"] as? NSArray {
for i in 0...loans.count-1 {
if let lender = loans[i] as? NSDictionary {
if let imageData = lender["image"] as? NSDictionary { imageID = imageData["id"] as! Int64 }
if let countryData = lender["location"] as? NSDictionary {
country = countryData["country"] as! String
town = countryData["town"] as! String
if let geo = countryData["geo"] as? NSDictionary {
latLongPair = geo["pairs"] as! String
}
}
let newLender = LenderData(context: PersistenceService.context)
newLender.id = lender["id"] as! Int64
newLender.name = lender["name"] as? String
newLender.image_id = imageID
newLender.activity = lender["activity"] as? String
newLender.use = lender["use"] as? String
newLender.loan_amount = lender["loan_amount"] as! Int32
newLender.funded_amount = lender["funded_amount"] as! Int32
newLender.country = country
newLender.town = town
newLender.geo_pairs = latLongPair
self.lendersTemp.append(newLender)
}
}
}
DispatchQueue.main.async {
completed()
}
} catch {
print("Error occured \(error)")
}
}
}
}
task.resume()
}
}
EDIT
Added the part of the code where I populate the lendersTemp array
I quote matt on this one from the comments:
So... You are appending to self.lendersTemp on a background thread but reading it on the main thread. Instead, get rid of it and just pass the data right thru the completed function.
Which is exactly what I did. And this worked
I'm trying to login and I'm doing tests right now and I'm trying when the log is correct I changed the title of the button but I get this error: value of type '(Any) -> ()' has no member ' SetTitle '. Then I leave you the code and a screenshot.
I need help because I'm blocked and I can not continue. All help will be appreciated. Thank you.
And this is my code
import UIKit
class LogViewController: UIViewController {
#IBOutlet weak var _username: UITextField!
#IBOutlet weak var _password: UITextField!
#IBAction func _login_button(_ sender: Any) {
let username = _username.text
let password = _password.text
if(username == "" || password == "")
{
return
}
DoLogin(username!, password!)
}
func DoLogin(_ user:String, _ psw:String)
{
let url = URL(string: "http://localhost/bill/userLogin.php")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let paramToSend = "username=" + user + "&password=" + psw
request.httpBody = paramToSend.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard let _:Data = data else
{
return
}
let json:Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let data_block = server_response["data"] as? NSDictionary
{
if let session_data = data_block["session"] as? String
{
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
DispatchQueue.main.async {
execute:self.LoginDone()
}
}
}
})
task.resume()
}
func LoginDone()
{
_username.isEnabled = false
_password.isEnabled = false
_login_button.setTitle("Logout", for: .normal)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You have issue that is connected with _login_button because it is #IBAction not #IBOutlet.
For solving of this issue drag outlet from storyboard and connect it with proper file.
And than set property of the button.
Example.
#IBOutlet weak var _login_button_outlet: UIButton!
func LoginDone()
{
_username.isEnabled = false
_password.isEnabled = false
_login_button_outlet.setTitle("Logout", for: .normal)
}
hi you trying to set the title to the _login_button which not the button its the #IBAction method so for setting the title you have to create #IBOutlet weak var _login_button: UIButton!.
I have created a project that will retrieve the extracted JSON data and display it in UITableview. I don't want to burden the app by downloading everything. So, only when user selected a row, will it retrieve the employee details. I'm using a page view controller so that the user is able to navigate each page by sliding the page. How can I sent the value I sent for page in dispatch_sync to detailviewcontroller page?
This is my code from managePageviewController
func viewDetailViewController(index: Int) -> DetailViewController? {
if let storyboard = storyboard,
page = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController {
let currentEmployee = employeeStore.searchEmployee[index]
getJson().testsearchJSON(currentEmployee.id, handler: {(employeeDetails) -> Void in
dispatch_sync(dispatch_get_main_queue(), {
page.employee = employeeDetails
page.employeeIndex = index
return page //fail here
})
})
}
return nil
}
This is my getJSON().testSearchJSON fund
func testsearchJSON(id:String, handler: (Employee) -> Void) {
let requestURL: NSURL = NSURL(string: (favUrl + id))!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
//retrieve data successfully
if (statusCode == 200) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
if data!.length > 0 && error == nil {
guard let name = json["firstName"] as? String,
let title = json["title"] as? String,
let id = json["id"]!,
let manager = json["managerName"] as? String,
let oa = json["oa"] as? String,
let email = json["email"] as? String,
let department = json["department"] as? String,
let division = json["division"] as? String,
let company = json["company"] as? String
else {
return;
}
let newEmployee = Employee(id: String(id), name: name, title: title, manager: manager, oa: oa, email: email, department: department, division: division, company: company)
//test
handler(newEmployee)
}
} catch {
print("Error with JSON: \(error)")
}
}
}
task.resume()
}
}
This is my page for DetailviewController
class DetailViewController: UIViewController, UITextFieldDelegate {
// MARK:- Propertise
#IBOutlet var employeePic: UIImageView! //employee picture
#IBOutlet var employeeName: UILabel! // name
#IBOutlet var employeeTitle: UILabel! //job title
#IBOutlet var dateCreated: UILabel!
#IBOutlet var managerName: UITextField!
#IBOutlet var oaName: UITextField!
#IBOutlet var emailField: UITextField!
#IBOutlet var departmentField: UITextField!
#IBOutlet var divisionField: UITextField!
#IBOutlet var companyField: UITextField!
var employee: Employee! {
//add applicataion name
didSet {
navigationItem.title = employee.name
}
}
//current employee index
var employeeIndex: Int!
let dateFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
formatter.timeStyle = .NoStyle
return formatter
}()
//MARK:- assign values
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
employeeName.text = employee.name
employeeTitle.text = "( " + employee.title + " )"
emailField.text = employee.email
managerName.text = employee.manager
dateCreated.text = dateFormatter.stringFromDate(employee.dateCreated)
oaName.text = employee.oa
departmentField.text = employee.department
divisionField.text = employee.division
companyField.text = employee.company
//retrieve image
employeePic.thumbnails()
employeePic.image = UIImage(named: "Default Image")
}
I think is this case it would be better to write data fetching in viewDidLoad or viewWillAppear function in DetailViewController. Something like that:
In MainViewController:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
viewDetailViewController(index : indexPath.row, employee: employeeStore.searchEmployee[indexPath.row])
}
func viewDetailViewController(index: Int, employee: Employee) {
let detailController = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController
detailController.currentEmployee = employee
// present/push/etc detail controller
present(detailViewController, animated: true, completion: nil)
}
In DetailViewController:
var employee : Employee?
...
override func viewDidLoad() {
super.viewDidLoad()
if let employee = currentEmployee {
getJson().testsearchJSON(employee.id, handler: {(employeeDetails) -> Void in
dispatch_sync(dispatch_get_main_queue(), {
//reload UI for employeeDetails
})
})
}
}
Also you can use GCD to wait for block loading, for example GCD groups.
Try to like this
func viewDetailViewController(index: Int) -> DetailViewController? {
if let storyboard = storyboard,
page = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController {
let currentEmployee = employeeStore.searchEmployee[index]
getJson().testsearchJSON(currentEmployee.id, handler: {(employeeDetails) -> Void in
page.employee = employeeDetails
page.employeeIndex = index
return page //fail here
})
}
return nil
}
func testsearchJSON(id:String, handler: (Employee) -> Void) {
let requestURL: NSURL = NSURL(string: (favUrl + id))!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let semaphore = dispatch_semaphore_create(0);
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
//retrieve data successfully
if (statusCode == 200) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
if data!.length > 0 && error == nil {
guard let name = json["firstName"] as? String,
let title = json["title"] as? String,
let id = json["id"]!,
let manager = json["managerName"] as? String,
let oa = json["oa"] as? String,
let email = json["email"] as? String,
let department = json["department"] as? String,
let division = json["division"] as? String,
let company = json["company"] as? String
else {
dispatch_semaphore_signal(semaphore);
return;
}
let newEmployee = Employee(id: String(id), name: name, title: title, manager: manager, oa: oa, email: email, department: department, division: division, company: company)
//test
handler(newEmployee)
dispatch_semaphore_signal(semaphore);
}
} catch {
dispatch_semaphore_signal(semaphore);
print("Error with JSON: \(error)")
}
}
}
task.resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}
}
I want to get the .get data from the access token but It seems impossible, I try since few hours to resolve my bug. How can I fix it? How can I resolve this bug and get response from WebView NSURL Request?
import Foundation
class User {
var id: String?
var userName: String?
var fullName: String?
var profilePicture: String?
var bio: String?
var website: String?
var mediaCount: String?
var followsCount: Int?
var followedByCount: Int?
init(userDict:[String:AnyObject]) {
self.id = userDict["id"] as? String
self.userName = userDict["username"] as? String
self.fullName = userDict["full_name"] as? String
self.profilePicture = userDict["profile_picture"] as? String
self.bio = userDict["bio"] as? String
self.website = userDict["website"] as? String
self.mediaCount = userDict["media"] as? String
if let countsDict = userDict["counts"] as? [String: AnyObject] {
self.followsCount = countsDict["follows"] as? Int
self.followedByCount = countsDict["followed_by"] as? Int
}
}
class func fetchUserInfo(withToken token: String, completionHandler: (User?, NSError?)->()) {
var user: User?
let url = NSURL(string: "https://api.instagram.com/v1/users/self/?access_token=\(token)")!
NSURLSession().dataTaskWithURL(url) { (data, response, error) in
guard error == nil else { return }
do {
if let jsonData = data,
let jsonDataDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) as? [String: AnyObject],
let jsonUserDict = jsonDataDict["data"] as? [String: AnyObject] {
user = User(userDict: jsonUserDict)
dispatch_async(dispatch_get_main_queue(), {
completionHandler(user, error)
})
}
} catch let err as NSError {
print(err.debugDescription)
}
}.resume()
}
var user = fetchUserInfo(withToken: "3923891960.a56f59d.7f2376b5acae4abf8f98eaf2a575adXX", completionHandler: updateUI)
func updateUI(user: User?, error: NSError?) {
avatarImage = user.profilePicture
mediaLabel.text = user.mediaCount
followsLabel.text = user.followsCount
followedBy.text = user.followedByCount
username.text = user.userName
full_name.text = user.fullName
bioLabel.text = user.bio
websiteLabel.text = user.website
}
}
//
// TableViewCell.swift
// CodeTaskInstagram
//
//
import UIKit
class TableViewCell: UITableViewCell {
#IBOutlet var avatarImage: UIImageView!
#IBOutlet var mediaLabel: UILabel!
#IBOutlet var followsLabel: UILabel!
#IBOutlet var followedBy: UILabel!
#IBOutlet var username: UILabel!
#IBOutlet var full_name: UILabel!
#IBOutlet var bioLabel: UILabel!
#IBOutlet var websiteLabel: UILabel!
#IBOutlet var idLabel: UILabel!
#IBOutlet var labelRecents: UILabel!
}
Instagram authorization with getting access_token in swift sample code:
Before use
Do not forget to fill
let redirectURI = ""
let clientID = ""
let clientSecret = ""
in NetworkManager.swift file
Code
User.swift
import Foundation
class User {
var id: String?
var userName: String?
var fullName: String?
var profilePicture: String?
var bio: String?
var website: String?
var followsCount: Int?
var followedByCount: Int?
init(userDict:[String:AnyObject]) {
self.id = userDict["id"] as? String
self.userName = userDict["username"] as? String
self.fullName = userDict["full_name"] as? String
self.profilePicture = userDict["profile_picture"] as? String
self.bio = userDict["bio"] as? String
self.website = userDict["website"] as? String
if let countsDict = userDict["counts"] as? [String: AnyObject] {
self.followsCount = countsDict["follows"] as? Int
self.followedByCount = countsDict["followed_by"] as? Int
}
}
var description: String {
get {
var result = ""
result += descriptionString("id", value: id)
result += descriptionString("userName", value: userName)
result += descriptionString("fullName", value: fullName)
result += descriptionString("profilePicture", value: profilePicture)
result += descriptionString("bio", value: bio)
result += descriptionString("website", value: website)
result += descriptionInt("followsCount", value: followsCount)
result += descriptionInt("followedByCount", value: followedByCount)
return result
}
}
private func descriptionString(name: String, value: String?) -> String{
var result = "\(name): "
if let _value = value {
result += _value
} else {
result += "nil"
}
return result + "\n"
}
private func descriptionInt(name: String, value: Int?) -> String{
var result = "\(name): "
if let _value = value {
result += "\(_value)"
} else {
result += "nil"
}
return result + "\n"
}
}
NetworkManager.swift
import Foundation
class NetworkManager {
var delegate: NetworkManagerDelegate?
var accessToken: String? = nil
var code: String? = nil
let baseURLString = "https://api.instagram.com"
let clientID = ""
let redirectURI = "https://www.instagram.com/"
let clientSecret = ""
static let InstagramResponseError = "InstagramResponseError"
}
// MARK: Get/Set
extension NetworkManager {
var authentificationUrl: String {
get {
return "\(baseURLString)/oauth/authorize/?client_id=\(clientID)&redirect_uri=\(redirectURI)&response_type=code"
}
}
class var sharedInstance: NetworkManager {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: NetworkManager? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = NetworkManager()
}
return Static.instance!
}
}
// MARK: Errors
extension NetworkManager {
func fetchError(jsonDataDict: [String: AnyObject]) -> NSError? {
var error: NSError? = nil
if let meta = jsonDataDict["meta"] as? [String:AnyObject] {
if let code = meta["code"] as? Int {
switch code {
case 400:
error = NSError(domain: NetworkManager.InstagramResponseError, code: code, userInfo: meta)
default:
break
}
}
}
return error
}
}
// MARK: Load Data
extension NetworkManager {
func newRequest(url: String, HTTPMethod: String, paramString: String?, completionHandler: ([String: AnyObject]?, NSURLResponse?, NSError?) -> Void) {
if let url = NSURL(string:url) {
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = HTTPMethod
if let paramString = paramString {
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)!
}
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
do {
var json: [String: AnyObject]? = nil
var responseError: NSError? = error
if let jsonData = data {
if let jsonDataDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) as? [String: AnyObject] {
if let _responseError = self.fetchError(jsonDataDict) {
responseError = _responseError
}
json = jsonDataDict
}
}
completionHandler(json, response, responseError)
} catch let err as NSError {
print(err.debugDescription)
}
}
task.resume()
}
}
func getAccessToken() {
if let code = self.code {
let urlString = "\(baseURLString)/oauth/access_token"
let paramString = "client_id=\(clientID)&client_secret=\(clientSecret)&grant_type=authorization_code&redirect_uri=\(redirectURI)&code=\(code)&scope=basic+public_content"
newRequest(urlString, HTTPMethod: "POST", paramString: paramString) { (json, response, error) in
if let json = json {
if let access_token = json["access_token"] as? String {
self.accessToken = access_token
NSLog("access_token: \(access_token)")
} else {
self.accessToken = nil
}
}
if let delegate = self.delegate {
delegate.getAccessTokenDidEnd(self.accessToken, error: error)
}
}
}
}
func loadProfile() {
if let accessToken = self.accessToken {
let urlString = "https://api.instagram.com/v1/users/self/?access_token=\(accessToken)"
newRequest(urlString, HTTPMethod: "GET", paramString: nil) { (json, response, error) in
var user: User? = nil
if let json = json {
if let userData = json["data"] as? [String:AnyObject] {
user = User(userDict: userData)
}
}
if let delegate = self.delegate {
delegate.loadProfileDidEnd(user, error: error)
}
}
}
}
}
NetworkManagerDelegate.swift
import Foundation
protocol NetworkManagerDelegate {
func getAccessTokenDidEnd(accessToken: String?, error: NSError?)
func loadProfileDidEnd(user: User?, error: NSError?)
}
ProfileTableViewCell.swift
import UIKit
class ProfileTableViewCell: UITableViewCell {
#IBOutlet var idLabel: UILabel!
#IBOutlet var userNameLabel: UILabel!
#IBOutlet var fullNameLabel: UILabel!
#IBOutlet var profilePictureLabel: UILabel!
#IBOutlet var bioLabel: UILabel!
#IBOutlet var websiteLabel: UILabel!
#IBOutlet var followsCountLabel: UILabel!
#IBOutlet var followedByCountLabel: UILabel!
func setData(user: User) {
setLabel(idLabel, value: user.id)
setLabel(userNameLabel, value: user.userName)
setLabel(fullNameLabel, value: user.fullName)
setLabel(profilePictureLabel, value: user.profilePicture)
setLabel(bioLabel, value: user.bio)
setLabel(websiteLabel, value: user.website)
setLabel(followsCountLabel, value: user.followsCount)
setLabel(followedByCountLabel, value: user.followedByCount)
}
private func setLabel(label: UILabel, value: String?) {
if let _value = value {
label.text = _value
} else {
label.text = "-"
}
}
private func setLabel(label: UILabel, value: Int?) {
if let _value = value {
label.text = "\(_value)"
} else {
label.text = "-"
}
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
private var webView: UIWebView!
#IBOutlet var tableView: UITableView!
let instagramManager = NetworkManager.sharedInstance
var user: User? = nil
override func viewDidLoad() {
super.viewDidLoad()
instagramManager.delegate = self
//log out
// deleteChache()
initWebView()
initTableView()
}
private func actionWhenUserLogedIn() {
self.webView.hidden = true
}
func deleteChache() {
NSURLCache.sharedURLCache().removeAllCachedResponses()
if let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies {
for cookie in cookies {
NSHTTPCookieStorage.sharedHTTPCookieStorage().deleteCookie(cookie)
}
}
}
}
// MARK: NetworkManagerDelegate
extension ViewController: NetworkManagerDelegate {
func initNetworkManager() {
instagramManager.delegate = self
}
func getAccessTokenDidEnd(accessToken: String?, error: NSError?) {
instagramManager.loadProfile()
}
func loadProfileDidEnd(user: User?, error: NSError?) {
self.user = user
dispatch_async(dispatch_get_main_queue()) {
self.tableView.hidden = false
self.tableView.reloadData()
}
}
}
// MARK: UIWebView
extension ViewController: UIWebViewDelegate {
private func initWebView() {
webView = UIWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height))
webView.delegate = self
view.addSubview(webView)
authorizationRequestInWebView()
}
private func authorizationRequestInWebView() {
if let url = NSURL(string: instagramManager.authentificationUrl) {
let request = NSURLRequest(URL: url, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10.0)
webView.loadRequest(request)
}
}
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let urlString = (request.URL?.absoluteString)!
if let range = urlString.rangeOfString(instagramManager.redirectURI + "?code=") {
let location = range.endIndex
let code = urlString.substringFromIndex(location)
instagramManager.code = code
NSLog("code: \(code)")
instagramManager.getAccessToken()
actionWhenUserLogedIn()
return false
}
return true
}
}
// MARK: UITableView
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func initTableView() {
tableView.delegate = self
tableView.dataSource = self
tableView.hidden = true
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ProfileTableViewCell")!
if let profileTableViewCell = cell as? ProfileTableViewCell {
if let user = self.user {
profileTableViewCell.setData(user)
}
}
return cell
}
}
Main.storyboard
I've been trying to display certain JSON data to the storyboard but for some reason have been unable. The part of it that works, is the the var name, which is a string, and it doesn't have to be converted so it just works. The part that I am having an issue with is trying to convert two Int64's to strings, but I have them listed as AnyObjects. It's really confusing me, but here is the issue in code:
The program runs fine, but it doesn't display any information for profileIconId and summonerLevel.
import UIKit
class ViewController: UIViewController, NSURLConnectionDelegate {
lazy var data = NSMutableData()
#IBOutlet weak var searchField: UITextField!
#IBOutlet weak var name: UILabel!
#IBOutlet weak var summonerLevel: UILabel!
#IBOutlet weak var profileIconId: UILabel!
#IBAction func enterButton(sender: AnyObject) {
startConnection()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startConnection(){
let urlPath: String = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/soon2challenger?api_key=(removed my private api key for obvious reasons)"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
connection.start()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.data.appendData(data)
}
func buttonAction(sender: UIButton!){
startConnection()
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var err: NSError
// throwing an error on the line below (can't figure out where the error message is)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
let include: AnyObject = jsonResult.objectForKey(searchField.text)!
var name1: AnyObject = include.objectForKey("name")!
var summLevel: AnyObject = include.objectForKey("summonerLevel")!
var profIconId: AnyObject = include.objectForKey("profileIconId")!
name.text = name1 as? String
profileIconId.text = profIconId as? String
summonerLevel.text = summLevel as? String
println(name1)
println(summLevel)
println(profIconId)
}
}
The code that processes and displays everything is in the connectionDidFinishLoading function at the very bottom of the code.
Here's a refactor of your connectionDidFinishLoading(_:) method that properly unwraps the values using optional bindings.
You might also consider using NSNumberFormatter instead of "\()".
func connectionDidFinishLoading(connection: NSURLConnection) {
var err: NSError?
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary,
let include = jsonResult.objectForKey(searchField.text) as? NSDictionary {
if let name1 = include[ "name" ] as? String {
name.text = name1
println(name1)
}
if let summLevel = include[ "summonerLevel" ] as? NSNumber {
summonerLevel.text = "\(summLevel.integerValue)"
println(summLevel)
}
if let profIconId = include[ "profileIconId" ] as? NSNumber {
profileIconId.text = "\(profIconId.integerValue)"
println(profIconId)
}
}
}