我有一个名为:' fetchPosts
'将数据从解析服务器提取到UicollectionViewController
,当我将此函数添加到任何其他方法时,如视图确实出现或创建一个按钮来更新视图我得到'
以NSException类型的未捕获异常终止
'不知道这里的问题是什么。
import UIKit
import AVKit
import AVFoundation
import CoreLocation
import Parse
class NewsfeedCollectionViewController : UICollectionViewController, CLLocationManagerDelegate
{
var searchController: UISearchController!
var posts: [Post]?
override func viewDidLoad() {
super.viewDidLoad()
if let user = PFUser.current() {
PFGeoPoint.geoPointForCurrentLocation { (geopoint, error) in
if geopoint != nil {
let geo = geopoint
user["location"] = geo
user.saveInBackground()
}
}
}
self.fetchPosts()
collectionView?.contentInset = UIEdgeInsets(top: 12, left: 4, bottom: 12, right: 4)
if let layout = collectionView?.collectionViewLayout as? PinterestLayout {
layout.delegate = self
}
}
func fetchPosts()
{
DispatchQueue.global(qos: .userInteractive).async {
self.posts = Post.fetchPosts(viewController: self)
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
}
}
@IBAction func reloadbtnPressed(_ sender: Any) {
fetchPosts()
}
}
extension NewsfeedCollectionViewController
{
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let posts = posts {
return posts.count
} else {
return 0
}
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PostCell", for: indexPath) as! PostCollectionViewCell
cell.post = self.posts?[indexPath.item]
return cell
}
}
extension NewsfeedCollectionViewController : PinterestLayoutDelegate
{
func collectionView(collectionView: UICollectionView, heightForPhotoAt indexPath: IndexPath, with width: CGFloat) -> CGFloat
{
if let post = posts?[indexPath.item], let _ = post.image {
let boundingRect = CGRect(x: 0, y: 0, width: width, height: CGFloat(MAXFLOAT))
// do {
// try postImageView.image = UIImage(data: image!.getData())
// }
// catch {
//
// }
do {
var image: UIImage
try image = UIImage(data: post.image!.getData())!
let rect = AVMakeRect(aspectRatio: image.size, insideRect: boundingRect)
return rect.size.height
}
catch {
return 1;
}
}
return 0
}
func collectionView(collectionView: UICollectionView, heightForCaptionAt indexPath: IndexPath, with width: CGFloat) -> CGFloat
{
if let post = posts?[indexPath.item] {
let topPadding = CGFloat(8)
let bottomPadding = CGFloat(12)
let captionFont = UIFont.systemFont(ofSize: 15)
let captionHeight = self.height(for: post.caption!, with: captionFont, width: width)
let profileImageHeight = CGFloat(36)
let height = topPadding + captionHeight + topPadding + profileImageHeight + bottomPadding
return height
}
return 0.0
}
func height(for text: String, with font: UIFont, width: CGFloat) -> CGFloat
{
let nsstring = NSString(string: text)
let maxHeight = CGFloat(64.0)
let textAttributes = [NSFontAttributeName : font]
let boundingRect = nsstring.boundingRect(with: CGSize(width: width, height: maxHeight), options: .usesLineFragmentOrigin, attributes: textAttributes, context: nil)
return ceil(boundingRect.height)
}
}
extension NewsfeedCollectionViewController : PostProtocol
{
func didFinishFetch(posts: [Post]?)
{
if (posts != nil) {
self.posts = posts
}
self.collectionView?.reloadData()
}
}
这里是我用来从服务器获取数据的Model Post文件:
import UIKit
import Parse
protocol PostProtocol: class {
func didFinishFetch(posts: [Post]?)
}
struct Post
{
var ID: String
var createdBy: User
var timeAgo: String?
var caption: String?
// var image: UIImage?
var image: PFFile?
var numberOfLikes: Int?
var numberOfComments: Int?
var numberOfShares: Int?
static weak var delegate: PostProtocol?
static func fetchPosts(viewController: PostProtocol) -> [Post]
{
var posts = [Post]()
delegate = viewController
let query = PFQuery(className: "posts");
if let latitude = (PFUser.current()?["location"] as AnyObject).latitude {
if let longitude = (PFUser.current()?["location"] as AnyObject).longitude {
let geoPoint = PFGeoPoint(latitude: latitude, longitude: longitude)
query.whereKey("postLocation", nearGeoPoint: geoPoint, withinKilometers: 1)
}
}
query.findObjectsInBackground { (objects: [PFObject]?, error: Error?) in
if error == nil {
for object in objects! {
let pfObject = object as PFObject
let ID = pfObject["uuid"] as! String
let caption = pfObject["title"] as! String
let likes = pfObject["likes"] as? Int
let comments = pfObject["comments"] as? Int
let shares = pfObject["shares"] as? Int
let image = pfObject["pic"] as? PFFile
let profileImage = pfObject["ava"] as? PFFile
let username = pfObject["username"] as? String
let user = User(username: username, profileImage: profileImage);
let from = pfObject.createdAt
let now = Date()
let components : NSCalendar.Unit = [.second, .minute, .hour, .day, .weekOfMonth]
let difference = (Calendar.current as NSCalendar).components(components, from: from! as Date, to: now, options: [])
var timeAgo: String = ""
// logic what to show: seconds, minuts, hours, days or weeks
if difference.second! <= 0 {
timeAgo = "now"
}
if difference.second! > 0 && difference.minute! == 0 {
timeAgo = "\(difference.second!)s."
}
if difference.minute! > 0 && difference.hour! == 0 {
timeAgo = "\(difference.minute!)m."
}
if difference.hour! > 0 && difference.day! == 0 {
timeAgo = "\(difference.hour!)h."
}
if difference.day! > 0 && difference.weekOfMonth! == 0 {
timeAgo = "\(difference.day!)d."
}
if difference.weekOfMonth! > 0 {
timeAgo = "\(difference.weekOfMonth!)w."
}
let post = Post(ID: ID, createdBy: user, timeAgo: timeAgo, caption: caption, image: image, numberOfLikes: likes, numberOfComments: comments, numberOfShares: shares)
posts.append(post);
}
delegate?.didFinishFetch(posts: posts)
}
}
return posts
}
}
struct User
{
var username: String?
var profileImage: PFFile?
}