Ios 以NSException Parse server类型的未捕获异常终止
我有一个名为“Ios 以NSException Parse server类型的未捕获异常终止,ios,swift,compiler-errors,Ios,Swift,Compiler Errors,我有一个名为“fetchPosts”的函数,当我将此函数添加到任何其他方法(如view Dod Display)或制作一个按钮以更新我获取的视图时,它将数据从解析服务器提取到UicollectionViewController” 以NSException类型的未捕获异常终止 “不知道这里有什么问题 import UIKit import AVKit import AVFoundation import CoreLocation import Parse class NewsfeedCollec
fetchPosts
”的函数,当我将此函数添加到任何其他方法(如view Dod Display)或制作一个按钮以更新我获取的视图时,它将数据从解析服务器提取到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()
}
}
下面是我用来从服务器获取数据的模型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?
}
导入UIKit
导入解析
协议后协议:类{
func didfishfetch(posts:[Post]?)
}
结构柱
{
变量ID:String
var createdBy:User
var timeAgo:字符串?
变量标题:字符串?
//var图像:UIImage?
var图像:PFFile?
var numberOfLikes:Int?
var numberOfComments:Int?
var numberOfShares:Int?
静态弱var委托:后协议?
静态函数fetchPosts(viewController:PostProtocol)->[Post]
{
var posts=[Post]()
委托=视图控制器
let query=PFQuery(类名:“posts”);
如果让纬度=(PFUser.current()?[“location”]作为任何对象)。纬度{
如果让经度=(PFUser.current()?[“location”]作为任何对象)。经度{
let geoPoint=PFGeoPoint(纬度:纬度,经度:经度)
query.whereKey(“postLocation”,nearGeoPoint:geoPoint,withinKilometers:1)
}
}
query.findObjectsInBackground{(对象:[PFObject]?,错误:error?)位于
如果错误==nil{
对于对象中的对象{
将pfObject=对象设为pfObject
让ID=pfObject[“uuid”]作为!字符串
将caption=pfObject[“title”]设为!字符串
让likes=pfObject[“likes”]as?Int
将comments=pfObject[“comments”]设为?Int
将shares=pfObject[“shares”]设为?Int
将image=pfObject[“pic”]设为PFFile
将profileImage=pfObject[“ava”]设为?PFFile
将username=pfObject[“username”]设为?字符串
让user=user(用户名:username,profileImage:profileImage);
let from=pfObject.createdAt
让我们现在=日期()
let组件:NSCalendar.Unit=[.second、.minute、.hour、.day、.weekOfMonth]
让差异=(Calendar.current作为NSCalendar)。组件(组件,from:from!作为日期,to:now,选项:[])
var timeAgo:String=“”
//逻辑显示:秒、分钟、小时、天或周
如果difference.second!0&&difference.minute!==0{
timeAgo=“\(差。秒!)s。”
}
如果difference.minute!>0&&difference.hour!==0{
timeAgo=“\(差。分钟!)m。”
}
如果difference.hour!>0&&difference.day!==0{
timeAgo=“\(差。小时!)h。”
}
如果difference.day!>0&&difference.weekOfMonth!==0{
timeAgo=“\(差异.天!)d。“
}
如果差异.weekOfMonth!>0{
timeAgo=“\(差异。周/月!)w。“
}
让post=post(ID:ID,createdBy:user,timeAgo:timeAgo,caption:caption,image:image,numberOfLikes:likes,numberOfComments:comments,numberOfShares:shares)
职位。追加(职位);
}
代理?.didfishfetch(posts:posts)
}
}
返回岗位
}
}
结构用户
{
var用户名:字符串?
var profileImage:PFFile?
}
1)能否提供UIImage的getData()方法的代码?看起来它是UIImage扩展中的一个方法。2) 为什么称之为:try image=UIImage(数据:post.image!.getData())!我尝试了image post.image,但出现了一个错误,无法将image类型转换为PFFile类型。open func getData()抛出->Data/**此方法类似于-getData
,但避免将整个PFFile
内容一次保存在内存中@指向将在必要时设置的n错误的param error指针@返回包含数据的流。如果提取时出错,则返回nil*/尝试检查数据是否可用并打印异常错误:if post.image?.isDataAvailable{var image:UIImage?do{let data=try post.image?.getData()image=UIImage(data:data)}catch{print(“发生错误:(error.localizedDescription)“}}我已经这样做了,但是我仍然得到了相同的错误!问题是函数“fetchPosts”在我用于ViewDidLoad时工作正常,并且它实际上在CollectionVIew上加载了文章,但是当我尝试在任何其他方法中重用时,我得到了这个错误。你能提供错误描述吗?