mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-28 06:08:33 +10:00
pass build
This commit is contained in:
@@ -30,9 +30,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
// 默认将 Realm 放在 App Group 里
|
||||
|
||||
let directory: NSURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(YepConfig.appGroupID)!
|
||||
let realmPath = directory.path!.stringByAppendingPathComponent("db.realm")
|
||||
let realmPath = directory.URLByAppendingPathComponent("db.realm").path!
|
||||
|
||||
return Realm.Configuration(path: realmPath, schemaVersion: 0, migrationBlock: { migration, oldSchemaVersion in
|
||||
return Realm.Configuration(path: realmPath, schemaVersion: 1, migrationBlock: { migration, oldSchemaVersion in
|
||||
})
|
||||
}
|
||||
|
||||
@@ -254,7 +254,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
// 主界面的头像
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
let conversations = realm.objects(Conversation)
|
||||
|
||||
for conversation in conversations {
|
||||
|
||||
@@ -89,8 +89,13 @@ class AvatarCache {
|
||||
|
||||
} else {
|
||||
dispatch_async(self.cacheQueue) {
|
||||
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if
|
||||
let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm()),
|
||||
let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm),
|
||||
let avatarFileURL = NSFileManager.yepAvatarURLWithName(avatar.avatarFileName),
|
||||
let image = UIImage(contentsOfFile: avatarFileURL.path!) {
|
||||
|
||||
@@ -111,20 +116,23 @@ class AvatarCache {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
var avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm())
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm)
|
||||
|
||||
if avatar == nil {
|
||||
|
||||
let avatarFileName = NSUUID().UUIDString
|
||||
|
||||
if let avatarURL = NSFileManager.saveAvatarImage(image, withName: avatarFileName) {
|
||||
let realm = Realm()
|
||||
if let _ = NSFileManager.saveAvatarImage(image, withName: avatarFileName) {
|
||||
|
||||
let newAvatar = Avatar()
|
||||
newAvatar.avatarURLString = avatarURLString
|
||||
newAvatar.avatarFileName = avatarFileName
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newAvatar)
|
||||
}
|
||||
}
|
||||
@@ -168,20 +176,22 @@ class AvatarCache {
|
||||
avatarCompletion.completion(avatar)
|
||||
}
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let avatarObject = avatarWithAvatarURLString(avatarURLString, inRealm: realm) {
|
||||
switch avatarCompletion.radius {
|
||||
case YepConfig.ConversationCell.avatarSize * 0.5:
|
||||
if avatarObject.roundMini.length == 0 {
|
||||
realm.write {
|
||||
avatarObject.roundMini = UIImageJPEGRepresentation(avatar, 0.9)
|
||||
let _ = try? realm.write {
|
||||
avatarObject.roundMini = UIImageJPEGRepresentation(avatar, 0.9)!
|
||||
}
|
||||
}
|
||||
case YepConfig.chatCellAvatarSize() * 0.5:
|
||||
if avatarObject.roundNano.length == 0 {
|
||||
realm.write {
|
||||
avatarObject.roundNano = UIImageJPEGRepresentation(avatar, 0.9)
|
||||
let _ = try? realm.write {
|
||||
avatarObject.roundNano = UIImageJPEGRepresentation(avatar, 0.9)!
|
||||
}
|
||||
}
|
||||
default:
|
||||
@@ -229,7 +239,11 @@ class AvatarCache {
|
||||
|
||||
// 再看看是否已有裁剪后的圆图
|
||||
|
||||
if let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm()) {
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm) {
|
||||
|
||||
switch radius {
|
||||
case YepConfig.ConversationCell.avatarSize * 0.5:
|
||||
@@ -257,7 +271,11 @@ class AvatarCache {
|
||||
|
||||
// 再看看是否已下载
|
||||
|
||||
if let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm()) {
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm) {
|
||||
|
||||
if let
|
||||
avatarFileURL = NSFileManager.yepAvatarURLWithName(avatar.avatarFileName),
|
||||
@@ -282,19 +300,21 @@ class AvatarCache {
|
||||
|
||||
// TODO 裁减 image
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
var avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm())
|
||||
let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm)
|
||||
|
||||
if avatar == nil {
|
||||
let avatarFileName = NSUUID().UUIDString
|
||||
|
||||
if let avatarURL = NSFileManager.saveAvatarImage(image, withName: avatarFileName) {
|
||||
if let _ = NSFileManager.saveAvatarImage(image, withName: avatarFileName) {
|
||||
let newAvatar = Avatar()
|
||||
newAvatar.avatarURLString = avatarURLString
|
||||
newAvatar.avatarFileName = avatarFileName
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newAvatar)
|
||||
}
|
||||
|
||||
@@ -303,12 +323,12 @@ class AvatarCache {
|
||||
if let oldAvatar = user.avatar {
|
||||
NSFileManager.deleteAvatarImageWithName(oldAvatar.avatarFileName)
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(oldAvatar)
|
||||
}
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.avatar = newAvatar
|
||||
}
|
||||
}
|
||||
@@ -372,7 +392,11 @@ class AvatarCache {
|
||||
|
||||
// 再看看是否已有裁剪后的圆图
|
||||
|
||||
if let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm()) {
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm) {
|
||||
|
||||
switch radius {
|
||||
case YepConfig.ConversationCell.avatarSize * 0.5:
|
||||
@@ -400,7 +424,9 @@ class AvatarCache {
|
||||
|
||||
dispatch_async(self.cacheQueue) {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
// 再看看是否已下载
|
||||
if let avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm) {
|
||||
@@ -427,7 +453,7 @@ class AvatarCache {
|
||||
|
||||
NSFileManager.deleteAvatarImageWithName(avatar.avatarFileName)
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(avatar)
|
||||
}
|
||||
}
|
||||
@@ -440,19 +466,21 @@ class AvatarCache {
|
||||
|
||||
// TODO: 裁减 image
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
var avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm)
|
||||
|
||||
if avatar == nil {
|
||||
let avatarFileName = NSUUID().UUIDString
|
||||
|
||||
if let avatarURL = NSFileManager.saveAvatarImage(image, withName: avatarFileName) {
|
||||
if let _ = NSFileManager.saveAvatarImage(image, withName: avatarFileName) {
|
||||
let newAvatar = Avatar()
|
||||
newAvatar.avatarURLString = avatarURLString
|
||||
newAvatar.avatarFileName = avatarFileName
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newAvatar)
|
||||
}
|
||||
|
||||
@@ -462,7 +490,7 @@ class AvatarCache {
|
||||
|
||||
if let avatar = avatar {
|
||||
if let user = userWithUserID(userID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.avatar = avatar
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,11 @@ class ImageCache {
|
||||
} else {
|
||||
dispatch_async(self.cacheQueue) {
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: Realm()) {
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
if let blurredThumbnailImage = blurredThumbnailImageOfMessage(message) {
|
||||
let bubbleBlurredThumbnailImage = blurredThumbnailImage.bubbleImageWithTailDirection(tailDirection, size: size).decodedImage()
|
||||
|
||||
@@ -102,7 +106,11 @@ class ImageCache {
|
||||
return
|
||||
}
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: Realm()) {
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
|
||||
let mediaType = message.mediaType
|
||||
|
||||
@@ -195,8 +203,12 @@ class ImageCache {
|
||||
mapSnapshotter.startWithCompletionHandler { (snapshot, error) -> Void in
|
||||
if error == nil {
|
||||
|
||||
let image = snapshot.image
|
||||
guard let snapshot = snapshot else {
|
||||
return
|
||||
}
|
||||
|
||||
let image = snapshot.image
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(image.size, true, image.scale)
|
||||
|
||||
let pinImage = UIImage(named: "icon_current_location")!
|
||||
@@ -226,12 +238,12 @@ class ImageCache {
|
||||
|
||||
let fileName = NSUUID().UUIDString
|
||||
|
||||
if let fileURL = NSFileManager.saveMessageImageData(data, withName: fileName) {
|
||||
if let _ = NSFileManager.saveMessageImageData(data, withName: fileName) {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
if let realm = message.realm {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.localAttachmentName = fileName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ class YepConfig {
|
||||
}
|
||||
|
||||
struct Profile {
|
||||
static let leftEdgeInset: CGFloat = Ruler.match(.iPhoneWidths(20, 38, 40))
|
||||
static let leftEdgeInset: CGFloat = Ruler.iPhoneHorizontal(20, 38, 40).value
|
||||
static let rightEdgeInset: CGFloat = leftEdgeInset
|
||||
static let introductionLabelFont = UIFont(name: "Helvetica-Light", size: 14)!
|
||||
}
|
||||
@@ -122,8 +122,8 @@ class YepConfig {
|
||||
|
||||
struct SocialWorkGithub {
|
||||
struct Repo {
|
||||
static let leftEdgeInset = Ruler.match(.iPhoneWidths(20, 38, 40))
|
||||
static let rightEdgeInset = leftEdgeInset
|
||||
static let leftEdgeInset: CGFloat = Ruler.iPhoneHorizontal(20, 38, 40).value
|
||||
static let rightEdgeInset: CGFloat = leftEdgeInset
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,8 +151,8 @@ class YepConfig {
|
||||
|
||||
static let locationNameLabelHeight: CGFloat = 20
|
||||
|
||||
static let mediaPreferredWidth: CGFloat = Ruler.match(.iPhoneWidths(192, 225, 250))
|
||||
static let mediaPreferredHeight: CGFloat = Ruler.match(.iPhoneWidths(208, 244, 270))
|
||||
static let mediaPreferredWidth: CGFloat = Ruler.iPhoneHorizontal(192, 225, 250).value
|
||||
static let mediaPreferredHeight: CGFloat = Ruler.iPhoneHorizontal(208, 244, 270).value
|
||||
|
||||
static let mediaMinWidth: CGFloat = 60
|
||||
static let mediaMinHeight: CGFloat = 30
|
||||
|
||||
@@ -57,8 +57,11 @@ func cleanRealmAndCaches() {
|
||||
|
||||
// clean Realm
|
||||
|
||||
let realm = Realm()
|
||||
realm.write {
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = try? realm.write {
|
||||
realm.deleteAll()
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,15 @@ let kMonth = kDay * 31
|
||||
let kYear = kDay * 365
|
||||
|
||||
func NSDateTimeAgoLocalizedStrings(key: String) -> String {
|
||||
|
||||
let resourcePath = NSBundle.mainBundle().resourcePath
|
||||
let path = resourcePath?.stringByAppendingPathComponent("NSDateTimeAgo.bundle")
|
||||
let bundle = NSBundle(path: path!)
|
||||
|
||||
|
||||
let resourceURL = NSBundle.mainBundle().resourceURL
|
||||
let URL = resourceURL?.URLByAppendingPathComponent("NSDateTimeAgo.bundle")
|
||||
let bundle = NSBundle(URL: URL!)
|
||||
|
||||
// let resourcePath = NSBundle.mainBundle().resourcePath
|
||||
// let path = resourcePath?.stringByAppendingPathComponent("NSDateTimeAgo.bundle")
|
||||
// let bundle = NSBundle(path: path!)
|
||||
|
||||
return NSLocalizedString(key, tableName: "NSDateTimeAgo", bundle: bundle!, comment: "")
|
||||
}
|
||||
|
||||
@@ -134,7 +138,7 @@ extension NSDate {
|
||||
|
||||
func getLocaleFormatUnderscoresWithValue(value: Double) -> String {
|
||||
|
||||
let localeCode = NSLocale.preferredLanguages().first as! String
|
||||
let localeCode = NSLocale.preferredLanguages().first
|
||||
|
||||
if localeCode == "ru" {
|
||||
let XY = Int(floor(value)) % 100
|
||||
|
||||
@@ -197,7 +197,7 @@ extension NSFileManager {
|
||||
class func cleanCachesDirectoryAtURL(cachesDirectoryURL: NSURL) {
|
||||
let fileManager = NSFileManager.defaultManager()
|
||||
|
||||
if let fileURLs = (try? fileManager.contentsOfDirectoryAtURL(cachesDirectoryURL, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions())) as? [NSURL] {
|
||||
if let fileURLs = (try? fileManager.contentsOfDirectoryAtURL(cachesDirectoryURL, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions())) {
|
||||
for fileURL in fileURLs {
|
||||
do {
|
||||
try fileManager.removeItemAtURL(fileURL)
|
||||
|
||||
@@ -71,7 +71,7 @@ public extension NSURLRequest {
|
||||
}
|
||||
}
|
||||
|
||||
if let headerFields = allHTTPHeaderFields as? [String: String] {
|
||||
if let headerFields = allHTTPHeaderFields {
|
||||
|
||||
for (field, value) in headerFields {
|
||||
switch field {
|
||||
|
||||
@@ -12,12 +12,12 @@ import Ruler
|
||||
extension UIImage {
|
||||
|
||||
func roundImageOfRadius(radius: CGFloat) -> UIImage {
|
||||
let radius = floor(radius - Ruler.match(.iPhoneWidths(0.5, 0.5, 1.5)))
|
||||
let radius = floor(radius - Ruler.iPhoneHorizontal(0.5, 0.5, 1.5).value)
|
||||
return self.largestCenteredSquareImage().resizeToTargetSize(CGSize(width: radius * 2, height: radius * 2)).roundImage()
|
||||
}
|
||||
|
||||
func squareImageOfSize(size: CGFloat) -> UIImage {
|
||||
let size = floor(size - Ruler.match(.iPhoneWidths(0.5, 0.5, 1.5)))
|
||||
let size = floor(size - Ruler.iPhoneHorizontal(0.5, 0.5, 1.5).value)
|
||||
return self.largestCenteredSquareImage().resizeToTargetSize(CGSize(width: size, height: size))
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ extension UIImage {
|
||||
|
||||
let cropSquare = CGRectMake(posX, posY, edge, edge)
|
||||
|
||||
let imageRef = CGImageCreateWithImageInRect(self.CGImage, cropSquare)
|
||||
let imageRef = CGImageCreateWithImageInRect(self.CGImage, cropSquare)!
|
||||
|
||||
return UIImage(CGImage: imageRef, scale: scale, orientation: self.imageOrientation)!
|
||||
return UIImage(CGImage: imageRef, scale: scale, orientation: self.imageOrientation)
|
||||
}
|
||||
|
||||
func resizeToTargetSize(targetSize: CGSize) -> UIImage {
|
||||
@@ -134,7 +134,7 @@ extension UIImage {
|
||||
}
|
||||
|
||||
let selfCGImage = self.CGImage
|
||||
var context = CGBitmapContextCreate(nil, Int(width), Int(height), CGImageGetBitsPerComponent(selfCGImage), 0, CGImageGetColorSpace(selfCGImage), CGImageGetBitmapInfo(selfCGImage));
|
||||
let context = CGBitmapContextCreate(nil, Int(width), Int(height), CGImageGetBitsPerComponent(selfCGImage), 0, CGImageGetColorSpace(selfCGImage), CGImageGetBitmapInfo(selfCGImage).rawValue);
|
||||
|
||||
CGContextConcatCTM(context, transform)
|
||||
|
||||
@@ -146,8 +146,8 @@ extension UIImage {
|
||||
CGContextDrawImage(context, CGRectMake(0,0, width, height), selfCGImage)
|
||||
}
|
||||
|
||||
let cgImage = CGBitmapContextCreateImage(context)
|
||||
return UIImage(CGImage: cgImage)!
|
||||
let cgImage = CGBitmapContextCreateImage(context)!
|
||||
return UIImage(CGImage: cgImage)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,8 +179,8 @@ extension UIImage {
|
||||
return self
|
||||
}
|
||||
|
||||
let cgImage = CGImageCreateWithImageInRect(self.CGImage, rect)
|
||||
return UIImage(CGImage: cgImage)!
|
||||
let cgImage = CGImageCreateWithImageInRect(self.CGImage, rect)!
|
||||
return UIImage(CGImage: cgImage)
|
||||
}
|
||||
/*
|
||||
private func bubblePathWithTailDirection(tailDirection: MessageImageTailDirection, size: CGSize) -> UIBezierPath {
|
||||
@@ -318,9 +318,9 @@ extension UIImage {
|
||||
|
||||
drawInRect(CGRect(origin: CGPointZero, size: size))
|
||||
|
||||
let cgImage = CGBitmapContextCreateImage(context)
|
||||
let cgImage = CGBitmapContextCreateImage(context)!
|
||||
|
||||
let image = UIImage(CGImage: cgImage)!
|
||||
let image = UIImage(CGImage: cgImage)
|
||||
|
||||
UIGraphicsEndImageContext()
|
||||
|
||||
@@ -356,7 +356,7 @@ extension UIImage {
|
||||
static let leftTail: UIImage = {
|
||||
let scale = UIScreen.mainScreen().scale
|
||||
let orientation: UIImageOrientation = .Up
|
||||
var maskImage = UIImage(CGImage: UIImage(named: "left_tail_image_bubble")!.CGImage, scale: scale, orientation: orientation)
|
||||
var maskImage = UIImage(CGImage: UIImage(named: "left_tail_image_bubble")!.CGImage!, scale: scale, orientation: orientation)
|
||||
maskImage = maskImage.resizableImageWithCapInsets(UIEdgeInsets(top: 25, left: 27, bottom: 20, right: 20), resizingMode: UIImageResizingMode.Stretch)
|
||||
return maskImage
|
||||
}()
|
||||
@@ -364,7 +364,7 @@ extension UIImage {
|
||||
static let rightTail: UIImage = {
|
||||
let scale = UIScreen.mainScreen().scale
|
||||
let orientation: UIImageOrientation = .UpMirrored
|
||||
var maskImage = UIImage(CGImage: UIImage(named: "left_tail_image_bubble")!.CGImage, scale: scale, orientation: orientation)
|
||||
var maskImage = UIImage(CGImage: UIImage(named: "left_tail_image_bubble")!.CGImage!, scale: scale, orientation: orientation)
|
||||
maskImage = maskImage.resizableImageWithCapInsets(UIEdgeInsets(top: 25, left: 27, bottom: 20, right: 20), resizingMode: UIImageResizingMode.Stretch)
|
||||
return maskImage
|
||||
}()
|
||||
@@ -372,7 +372,7 @@ extension UIImage {
|
||||
|
||||
func bubbleImageWithTailDirection(tailDirection: MessageImageTailDirection, size: CGSize, forMap: Bool = false) -> UIImage {
|
||||
|
||||
let orientation: UIImageOrientation = tailDirection == .Left ? .Up : .UpMirrored
|
||||
//let orientation: UIImageOrientation = tailDirection == .Left ? .Up : .UpMirrored
|
||||
|
||||
let maskImage: UIImage
|
||||
|
||||
@@ -426,7 +426,7 @@ extension UIImage {
|
||||
let newRect = CGRectIntegral(CGRect(origin: CGPointZero, size: size))
|
||||
let transposedRect = CGRect(origin: CGPointZero, size: CGSize(width: size.height, height: size.width))
|
||||
|
||||
let bitmapContext = CGBitmapContextCreate(nil, Int(newRect.width), Int(newRect.height), CGImageGetBitsPerComponent(CGImage), 0, CGImageGetColorSpace(CGImage), CGImageGetBitmapInfo(CGImage))
|
||||
let bitmapContext = CGBitmapContextCreate(nil, Int(newRect.width), Int(newRect.height), CGImageGetBitsPerComponent(CGImage), 0, CGImageGetColorSpace(CGImage), CGImageGetBitmapInfo(CGImage).rawValue)
|
||||
|
||||
CGContextConcatCTM(bitmapContext, transform)
|
||||
|
||||
@@ -434,7 +434,7 @@ extension UIImage {
|
||||
|
||||
CGContextDrawImage(bitmapContext, drawTransposed ? transposedRect : newRect, CGImage)
|
||||
|
||||
let newCGImage = CGBitmapContextCreateImage(bitmapContext)
|
||||
let newCGImage = CGBitmapContextCreateImage(bitmapContext)!
|
||||
let newImage = UIImage(CGImage: newCGImage)
|
||||
|
||||
return newImage
|
||||
@@ -503,12 +503,12 @@ extension UIImage {
|
||||
let imageRef = CGImage
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)
|
||||
let context = CGBitmapContextCreate(nil, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef), 8, 0, colorSpace, bitmapInfo)
|
||||
let context = CGBitmapContextCreate(nil, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef), 8, 0, colorSpace, bitmapInfo.rawValue)
|
||||
|
||||
if let context = context {
|
||||
let rect = CGRectMake(0, 0, CGFloat(CGImageGetWidth(imageRef)), CGFloat(CGImageGetHeight(imageRef)))
|
||||
CGContextDrawImage(context, rect, imageRef)
|
||||
let decompressedImageRef = CGBitmapContextCreateImage(context)
|
||||
let decompressedImageRef = CGBitmapContextCreateImage(context)!
|
||||
|
||||
return UIImage(CGImage: decompressedImageRef, scale: scale, orientation: imageOrientation) ?? self
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ class YepAlert {
|
||||
|
||||
let action: UIAlertAction = UIAlertAction(title: dismissTitle, style: .Default) { action -> Void in
|
||||
if let finishedAction = finishedAction {
|
||||
if let textField = alertController.textFields?.first as? UITextField {
|
||||
finishedAction(text: textField.text)
|
||||
if let textField = alertController.textFields?.first, text = textField.text {
|
||||
finishedAction(text: text)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,8 +77,8 @@ class YepAlert {
|
||||
alertController.addAction(_cancelAction)
|
||||
|
||||
let _confirmAction: UIAlertAction = UIAlertAction(title: confirmTitle, style: .Default) { action -> Void in
|
||||
if let textField = alertController.textFields?.first as? UITextField {
|
||||
confirmAction?(text: textField.text)
|
||||
if let textField = alertController.textFields?.first, text = textField.text {
|
||||
confirmAction?(text: text)
|
||||
}
|
||||
}
|
||||
alertController.addAction(_confirmAction)
|
||||
|
||||
@@ -17,7 +17,7 @@ func thumbnailImageOfVideoInVideoURL(videoURL: NSURL) -> UIImage? {
|
||||
|
||||
var actualTime: CMTime = CMTimeMake(0, 0)
|
||||
|
||||
guard let cgImage = try imageGenerator.copyCGImageAtTime(CMTimeMakeWithSeconds(0.0, 600), actualTime: &actualTime) else {
|
||||
guard let cgImage = try? imageGenerator.copyCGImageAtTime(CMTimeMakeWithSeconds(0.0, 600), actualTime: &actualTime) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class YepHUD: NSObject {
|
||||
|
||||
self.sharedInstance.activityIndicator.alpha = 0
|
||||
self.sharedInstance.activityIndicator.transform = CGAffineTransformMakeScale(0.0001, 0.0001)
|
||||
UIView.animateWithDuration(0.2, delay: 0.0, options: UIViewAnimationOptions(0), animations: { () -> Void in
|
||||
UIView.animateWithDuration(0.2, delay: 0.0, options: UIViewAnimationOptions(rawValue: 0), animations: { () -> Void in
|
||||
self.sharedInstance.activityIndicator.transform = CGAffineTransformMakeScale(1.0, 1.0)
|
||||
self.sharedInstance.activityIndicator.alpha = 1
|
||||
|
||||
@@ -107,7 +107,7 @@ class YepHUD: NSObject {
|
||||
}, completion: { (finished) -> Void in
|
||||
self.sharedInstance.activityIndicator.removeFromSuperview()
|
||||
|
||||
UIView.animateWithDuration(0.1, delay: 0.0, options: UIViewAnimationOptions(0), animations: { () -> Void in
|
||||
UIView.animateWithDuration(0.1, delay: 0.0, options: UIViewAnimationOptions(rawValue: 0), animations: { () -> Void in
|
||||
self.sharedInstance.containerView.alpha = 0
|
||||
|
||||
}, completion: { (finished) -> Void in
|
||||
|
||||
@@ -123,7 +123,7 @@ class YepUserDefaults {
|
||||
|
||||
class func userNeedRelogin() {
|
||||
|
||||
if let token = v1AccessToken.value {
|
||||
if let _ = v1AccessToken.value {
|
||||
|
||||
cleanRealmAndCaches()
|
||||
|
||||
@@ -170,15 +170,17 @@ class YepUserDefaults {
|
||||
return Listenable<String?>(nickname) { nickname in
|
||||
defaults.setObject(nickname, forKey: nicknameKey)
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
nickname = nickname,
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
realm.beginWrite()
|
||||
me.nickname = nickname
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
me.nickname = nickname
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -189,15 +191,17 @@ class YepUserDefaults {
|
||||
return Listenable<String?>(introduction) { introduction in
|
||||
defaults.setObject(introduction, forKey: introductionKey)
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
introduction = introduction,
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
realm.beginWrite()
|
||||
me.introduction = introduction
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
me.introduction = introduction
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -208,16 +212,17 @@ class YepUserDefaults {
|
||||
return Listenable<String?>(avatarURLString) { avatarURLString in
|
||||
defaults.setObject(avatarURLString, forKey: avatarURLStringKey)
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
avatarURLString = avatarURLString,
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
let realm = Realm()
|
||||
realm.beginWrite()
|
||||
me.avatarURLString = avatarURLString
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
me.avatarURLString = avatarURLString
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -228,15 +233,17 @@ class YepUserDefaults {
|
||||
return Listenable<String?>(badge) { badge in
|
||||
defaults.setObject(badge, forKey: badgeKey)
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
badge = badge,
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
realm.beginWrite()
|
||||
me.badge = badge
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
me.badge = badge
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
+19
-17
@@ -154,9 +154,9 @@ class User: Object {
|
||||
|
||||
dynamic var doNotDisturb: UserDoNotDisturb?
|
||||
|
||||
let learningSkills = List<UserSkill>()
|
||||
let masterSkills = List<UserSkill>()
|
||||
let socialAccountProviders = List<UserSocialAccountProvider>()
|
||||
var learningSkills = List<UserSkill>()
|
||||
var masterSkills = List<UserSkill>()
|
||||
var socialAccountProviders = List<UserSocialAccountProvider>()
|
||||
|
||||
var messages: [Message] {
|
||||
return linkingObjects(Message.self, forProperty: "fromFriend")
|
||||
@@ -185,7 +185,7 @@ class Group: Object {
|
||||
dynamic var createdUnixTime: NSTimeInterval = NSDate().timeIntervalSince1970
|
||||
|
||||
dynamic var owner: User?
|
||||
let members = List<User>()
|
||||
var members = List<User>()
|
||||
|
||||
var conversation: Conversation? {
|
||||
let conversations = linkingObjects(Conversation.self, forProperty: "withGroup")
|
||||
@@ -396,13 +396,13 @@ class Conversation: Object {
|
||||
// MARK: Helpers
|
||||
|
||||
func normalFriends() -> Results<User> {
|
||||
let realm = Realm()
|
||||
let realm = try! Realm()
|
||||
let predicate = NSPredicate(format: "friendState = %d", UserFriendState.Normal.rawValue)
|
||||
return realm.objects(User).filter(predicate)
|
||||
}
|
||||
|
||||
func normalUsers() -> Results<User> {
|
||||
let realm = Realm()
|
||||
let realm = try! Realm()
|
||||
let predicate = NSPredicate(format: "friendState != %d", UserFriendState.Blocked.rawValue)
|
||||
return realm.objects(User).filter(predicate)
|
||||
}
|
||||
@@ -459,7 +459,7 @@ func messageWithMessageID(messageID: String, inRealm realm: Realm) -> Message? {
|
||||
println("Warning: same messageID: \(messages.count), \(messageID)")
|
||||
|
||||
// 治标未读
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
for message in messages {
|
||||
message.readed = true
|
||||
}
|
||||
@@ -513,7 +513,7 @@ func tryGetOrCreateMeInRealm(realm: Realm) -> User? {
|
||||
me.avatarURLString = avatarURLString
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(me)
|
||||
}
|
||||
|
||||
@@ -546,7 +546,7 @@ func messagesInConversationFromFriend(conversation: Conversation) -> Results<Mes
|
||||
return realm.objects(Message).filter(predicate).sorted("createdUnixTime", ascending: true)
|
||||
|
||||
} else {
|
||||
let realm = Realm()
|
||||
let realm = try! Realm()
|
||||
return realm.objects(Message).filter(predicate).sorted("createdUnixTime", ascending: true)
|
||||
}
|
||||
}
|
||||
@@ -559,7 +559,7 @@ func messagesInConversation(conversation: Conversation) -> Results<Message> {
|
||||
return realm.objects(Message).filter(predicate).sorted("createdUnixTime", ascending: true)
|
||||
|
||||
} else {
|
||||
let realm = Realm()
|
||||
let realm = try! Realm()
|
||||
return realm.objects(Message).filter(predicate).sorted("createdUnixTime", ascending: true)
|
||||
}
|
||||
}
|
||||
@@ -579,13 +579,13 @@ func messagesUnreadSentByMe(inRealm realm: Realm) -> Results<Message> {
|
||||
}
|
||||
|
||||
func messagesOfConversation(conversation: Conversation, inRealm realm: Realm) -> Results<Message> {
|
||||
let predicate = NSPredicate(format: "conversation = %@", conversation)
|
||||
let predicate = NSPredicate(format: "conversation = %@", argumentArray: [conversation])
|
||||
let messages = realm.objects(Message).filter(predicate).sorted("createdUnixTime", ascending: true)
|
||||
return messages
|
||||
}
|
||||
|
||||
func unReadMessagesOfConversation(conversation: Conversation, inRealm realm: Realm) -> Results<Message> {
|
||||
let predicate = NSPredicate(format: "conversation = %@ AND readed = 0", conversation)
|
||||
let predicate = NSPredicate(format: "conversation = %@ AND readed = 0", argumentArray: [conversation])
|
||||
let messages = realm.objects(Message).filter(predicate).sorted("createdUnixTime", ascending: true)
|
||||
return messages
|
||||
}
|
||||
@@ -666,7 +666,7 @@ func blurredThumbnailImageOfMessage(message: Message) -> UIImage? {
|
||||
if let mediaMetaData = message.mediaMetaData {
|
||||
if let metaDataInfo = decodeJSON(mediaMetaData.data) {
|
||||
if let blurredThumbnailString = metaDataInfo[YepConfig.MetaData.blurredThumbnailString] as? String {
|
||||
if let data = NSData(base64EncodedString: blurredThumbnailString, options: NSDataBase64DecodingOptions(0)) {
|
||||
if let data = NSData(base64EncodedString: blurredThumbnailString, options: NSDataBase64DecodingOptions(rawValue: 0)) {
|
||||
return UIImage(data: data)
|
||||
}
|
||||
}
|
||||
@@ -725,11 +725,13 @@ func videoMetaOfMessage(message: Message) -> (width: CGFloat, height: CGFloat)?
|
||||
|
||||
func updateUserWithUserID(userID: String, useUserInfo userInfo: JSONDictionary) {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let user = userWithUserID(userID, inRealm: realm) {
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
|
||||
// 更新用户信息
|
||||
|
||||
@@ -770,13 +772,13 @@ func updateUserWithUserID(userID: String, useUserInfo userInfo: JSONDictionary)
|
||||
if let learningSkillsData = userInfo["learning_skills"] as? [JSONDictionary] {
|
||||
user.learningSkills.removeAll()
|
||||
let userSkills = userSkillsFromSkillsData(learningSkillsData, inRealm: realm)
|
||||
user.learningSkills.extend(userSkills)
|
||||
user.learningSkills.appendContentsOf(userSkills)
|
||||
}
|
||||
|
||||
if let masterSkillsData = userInfo["master_skills"] as? [JSONDictionary] {
|
||||
user.masterSkills.removeAll()
|
||||
let userSkills = userSkillsFromSkillsData(masterSkillsData, inRealm: realm)
|
||||
user.masterSkills.extend(userSkills)
|
||||
user.masterSkills.appendContentsOf(userSkills)
|
||||
}
|
||||
|
||||
// 更新 Social Account Provider
|
||||
|
||||
@@ -105,15 +105,17 @@ class FayeService: NSObject, MZFayeClientDelegate {
|
||||
if let messageDataInfo = messageInfo["message"] as? JSONDictionary {
|
||||
|
||||
if let
|
||||
recipientID = messageDataInfo["recipient_id"] as? String,
|
||||
//recipientID = messageDataInfo["recipient_id"] as? String,
|
||||
messageID = messageDataInfo["id"] as? String {
|
||||
|
||||
println("Mark Message \(messageID) As Read")
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.sendState = MessageSendState.Read.rawValue
|
||||
}
|
||||
|
||||
@@ -161,7 +163,9 @@ class FayeService: NSObject, MZFayeClientDelegate {
|
||||
private func saveMessageWithMessageInfo(messageInfo: JSONDictionary) {
|
||||
//这里不用 realmQueue 是为了下面的通知同步,用了 realmQueue 可能导致数据更新慢于通知
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
syncMessageWithMessageInfo(messageInfo, inRealm: realm) { messageIDs in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
@@ -57,28 +57,28 @@ public class MonkeyKing {
|
||||
|
||||
if let data = UIPasteboard.generalPasteboard().dataForPasteboardType("content") {
|
||||
|
||||
if let dic = (try? NSPropertyListSerialization.propertyListWithData(data, options: Int(NSPropertyListMutabilityOptions.Immutable.rawValue), format: nil)) as? NSDictionary {
|
||||
|
||||
for account in sharedMonkeyKing.accountSet {
|
||||
|
||||
switch account {
|
||||
|
||||
case .WeChat(let appID):
|
||||
|
||||
if let dic = dic[appID] as? NSDictionary {
|
||||
|
||||
if let result = dic["result"]?.integerValue {
|
||||
|
||||
let success = (result == 0)
|
||||
|
||||
sharedMonkeyKing.latestFinish?(success)
|
||||
|
||||
return success
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if let dic = (try? NSPropertyListSerialization.propertyListWithData(data, options: Int(NSPropertyListMutabilityOptions.Immutable.rawValue), format: nil)) as? NSDictionary {
|
||||
//
|
||||
// for account in sharedMonkeyKing.accountSet {
|
||||
//
|
||||
// switch account {
|
||||
//
|
||||
// case .WeChat(let appID):
|
||||
//
|
||||
// if let dic = dic[appID] as? NSDictionary {
|
||||
//
|
||||
// if let result = dic["result"]?.integerValue {
|
||||
//
|
||||
// let success = (result == 0)
|
||||
//
|
||||
// sharedMonkeyKing.latestFinish?(success)
|
||||
//
|
||||
// return success
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
return false
|
||||
@@ -137,7 +137,7 @@ public class MonkeyKing {
|
||||
case .WeChat:
|
||||
for account in sharedMonkeyKing.accountSet {
|
||||
switch account {
|
||||
case .WeChat(let appID):
|
||||
case .WeChat:
|
||||
return account.isAppInstalled
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,11 @@ class YepAudioService: NSObject {
|
||||
var audioPlayer: AVAudioPlayer?
|
||||
|
||||
func prepareAudioRecorderWithFileURL(fileURL: NSURL, audioRecorderDelegate: AVAudioRecorderDelegate) {
|
||||
|
||||
audioFileURL = fileURL
|
||||
|
||||
let settings = [
|
||||
AVFormatIDKey: kAudioFormatMPEG4AAC,
|
||||
let settings: [String: AnyObject] = [
|
||||
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
|
||||
AVEncoderAudioQualityKey : AVAudioQuality.Max.rawValue,
|
||||
AVEncoderBitRateKey : 64000,
|
||||
AVNumberOfChannelsKey: 2,
|
||||
@@ -42,8 +43,8 @@ class YepAudioService: NSObject {
|
||||
|
||||
var error: NSError?
|
||||
do {
|
||||
audioRecorder = try AVAudioRecorder(URL: fileURL, settings: settings as [NSObject : AnyObject])
|
||||
} catch var error1 as NSError {
|
||||
audioRecorder = try AVAudioRecorder(URL: fileURL, settings: settings)
|
||||
} catch let error1 as NSError {
|
||||
error = error1
|
||||
audioRecorder = nil
|
||||
}
|
||||
@@ -139,7 +140,7 @@ class YepAudioService: NSObject {
|
||||
}
|
||||
dispatch_async(queue, { () -> Void in
|
||||
// AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: AVAudioSessionCategoryOptions.DefaultToSpeaker,error: nil)
|
||||
AVAudioSession.sharedInstance().setActive(false, withOptions: AVAudioSessionSetActiveOptions.NotifyOthersOnDeactivation)
|
||||
let _ = try? AVAudioSession.sharedInstance().setActive(false, withOptions: AVAudioSessionSetActiveOptions.NotifyOthersOnDeactivation)
|
||||
})
|
||||
|
||||
self.checkRecordTimeoutTimer?.invalidate()
|
||||
|
||||
@@ -20,7 +20,7 @@ class YepDownloader: NSObject {
|
||||
}()
|
||||
|
||||
class func updateAttachmentOfMessage(message: Message, withAttachmentFileName attachmentFileName: String, inRealm realm: Realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.localAttachmentName = attachmentFileName
|
||||
|
||||
if message.mediaType == MessageMediaType.Video.rawValue {
|
||||
@@ -35,7 +35,7 @@ class YepDownloader: NSObject {
|
||||
}
|
||||
|
||||
class func updateThumbnailOfMessage(message: Message, withThumbnailFileName thumbnailFileName: String, inRealm realm: Realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.localThumbnailName = thumbnailFileName
|
||||
|
||||
if message.mediaType == MessageMediaType.Video.rawValue {
|
||||
@@ -106,7 +106,9 @@ class YepDownloader: NSObject {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
|
||||
@@ -162,7 +164,9 @@ class YepDownloader: NSObject {
|
||||
thumbnailFinishedAction = { data in
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
|
||||
|
||||
@@ -33,45 +33,39 @@ class YepLocationService: NSObject, CLLocationManagerDelegate {
|
||||
var address: String?
|
||||
let geocoder = CLGeocoder()
|
||||
|
||||
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
|
||||
|
||||
if let newLocation = newLocation {
|
||||
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
|
||||
|
||||
// 尽量减少对服务器的请求和反向查询
|
||||
// 尽量减少对服务器的请求和反向查询
|
||||
|
||||
if let oldLocation = oldLocation {
|
||||
let distance = newLocation.distanceFromLocation(oldLocation)
|
||||
|
||||
let distance = newLocation.distanceFromLocation(oldLocation)
|
||||
if distance < YepConfig.Location.distanceThreshold {
|
||||
return
|
||||
}
|
||||
|
||||
if distance < YepConfig.Location.distanceThreshold {
|
||||
return
|
||||
}
|
||||
}
|
||||
updateMyselfWithInfo(["latitude": newLocation.coordinate.latitude, "longitude": newLocation.coordinate.longitude], failureHandler: nil, completion: { _ in
|
||||
})
|
||||
|
||||
updateMyselfWithInfo(["latitude": newLocation.coordinate.latitude, "longitude": newLocation.coordinate.longitude], failureHandler: nil, completion: { _ in
|
||||
})
|
||||
geocoder.reverseGeocodeLocation(newLocation, completionHandler: { (placemarks, error) in
|
||||
|
||||
geocoder.reverseGeocodeLocation(newLocation, completionHandler: { (placemarks, error) in
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if (error != nil) {
|
||||
println("self reverse geocode fail: \(error?.localizedDescription)")
|
||||
|
||||
if (error != nil) {
|
||||
println("self reverse geocode fail: \(error.localizedDescription)")
|
||||
} else {
|
||||
if let placemarks = placemarks {
|
||||
|
||||
} else {
|
||||
if let placemarks = placemarks as? [CLPlacemark] {
|
||||
if let firstPlacemark = placemarks.first {
|
||||
|
||||
if let firstPlacemark = placemarks.first {
|
||||
self?.address = firstPlacemark.locality ?? (firstPlacemark.name ?? firstPlacemark.country)
|
||||
|
||||
self?.address = firstPlacemark.locality ?? (firstPlacemark.name ?? firstPlacemark.country)
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName("YepLocationUpdated", object: nil)
|
||||
}
|
||||
NSNotificationCenter.defaultCenter().postNotificationName("YepLocationUpdated", object: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public enum Reason: CustomStringConvertible {
|
||||
case CouldNotParseJSON
|
||||
case NoData
|
||||
case NoSuccessStatusCode(statusCode: Int)
|
||||
case Other(NSError)
|
||||
case Other(NSError?)
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
@@ -58,7 +58,7 @@ public enum Reason: CustomStringConvertible {
|
||||
case .NoSuccessStatusCode(let statusCode):
|
||||
return "NoSuccessStatusCode: \(statusCode)"
|
||||
case .Other(let error):
|
||||
return "Other, Error: \(error.description)"
|
||||
return "Other, Error: \(error?.description)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1361,7 +1361,9 @@ func officialMessages(completion completion: Int -> Void) {
|
||||
|
||||
// Yep Team
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return 0
|
||||
}
|
||||
|
||||
var sender = userWithUserID(senderID, inRealm: realm)
|
||||
|
||||
@@ -1372,7 +1374,7 @@ func officialMessages(completion completion: Int -> Void) {
|
||||
|
||||
newUser.friendState = UserFriendState.Yep.rawValue
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newUser)
|
||||
}
|
||||
|
||||
@@ -1390,7 +1392,7 @@ func officialMessages(completion completion: Int -> Void) {
|
||||
newConversation.type = ConversationType.OneToOne.rawValue
|
||||
newConversation.withFriend = sender
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newConversation)
|
||||
}
|
||||
}
|
||||
@@ -1414,7 +1416,7 @@ func officialMessages(completion completion: Int -> Void) {
|
||||
newMessage.createdUnixTime = updatedUnixTime
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newMessage)
|
||||
}
|
||||
|
||||
@@ -1422,12 +1424,12 @@ func officialMessages(completion completion: Int -> Void) {
|
||||
}
|
||||
|
||||
if let message = message {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.fromFriend = sender
|
||||
}
|
||||
|
||||
if let conversation = sender?.conversation {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.conversation = conversation
|
||||
|
||||
}
|
||||
@@ -1676,9 +1678,9 @@ func sendLocationWithLocationInfo(locationInfo: PickLocationViewController.Locat
|
||||
func createAndSendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: String?, orFileData fileData: NSData?, metaData: String?, fillMoreInfo: (JSONDictionary -> JSONDictionary)?, toRecipient recipientID: String, recipientType: String, afterCreatedMessage: (Message) -> Void, failureHandler: ((Reason, String?) -> Void)?, completion: (success: Bool) -> Void) {
|
||||
// 因为 message_id 必须来自远端,线程无法切换,所以这里暂时没用 realmQueue // TOOD: 也许有办法
|
||||
|
||||
let realm = Realm()
|
||||
|
||||
realm.beginWrite()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
let message = Message()
|
||||
|
||||
@@ -1692,15 +1694,14 @@ func createAndSendMessageWithMediaType(mediaType: MessageMediaType, inFilePath f
|
||||
|
||||
message.mediaType = mediaType.rawValue
|
||||
|
||||
realm.add(message)
|
||||
|
||||
realm.commitWrite()
|
||||
|
||||
let _ = try? realm.write {
|
||||
realm.add(message)
|
||||
}
|
||||
|
||||
// 消息来自于自己
|
||||
|
||||
if let me = tryGetOrCreateMeInRealm(realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.fromFriend = me
|
||||
}
|
||||
}
|
||||
@@ -1709,51 +1710,50 @@ func createAndSendMessageWithMediaType(mediaType: MessageMediaType, inFilePath f
|
||||
|
||||
var conversation: Conversation? = nil
|
||||
|
||||
realm.beginWrite()
|
||||
|
||||
if recipientType == "User" {
|
||||
if let withFriend = userWithUserID(recipientID, inRealm: realm) {
|
||||
conversation = withFriend.conversation
|
||||
}
|
||||
|
||||
} else {
|
||||
if let withGroup = groupWithGroupID(recipientID, inRealm: realm) {
|
||||
conversation = withGroup.conversation
|
||||
}
|
||||
}
|
||||
|
||||
if conversation == nil {
|
||||
let newConversation = Conversation()
|
||||
let _ = try? realm.write {
|
||||
|
||||
if recipientType == "User" {
|
||||
newConversation.type = ConversationType.OneToOne.rawValue
|
||||
|
||||
if let withFriend = userWithUserID(recipientID, inRealm: realm) {
|
||||
newConversation.withFriend = withFriend
|
||||
conversation = withFriend.conversation
|
||||
}
|
||||
|
||||
} else {
|
||||
newConversation.type = ConversationType.Group.rawValue
|
||||
|
||||
if let withGroup = groupWithGroupID(recipientID, inRealm: realm) {
|
||||
newConversation.withGroup = withGroup
|
||||
conversation = withGroup.conversation
|
||||
}
|
||||
}
|
||||
|
||||
conversation = newConversation
|
||||
}
|
||||
if conversation == nil {
|
||||
let newConversation = Conversation()
|
||||
|
||||
if let conversation = conversation {
|
||||
conversation.updatedUnixTime = message.createdUnixTime // 关键哦
|
||||
message.conversation = conversation
|
||||
if recipientType == "User" {
|
||||
newConversation.type = ConversationType.OneToOne.rawValue
|
||||
|
||||
tryCreateSectionDateMessageInConversation(conversation, beforeMessage: message, inRealm: realm) { sectionDateMessage in
|
||||
realm.add(sectionDateMessage)
|
||||
if let withFriend = userWithUserID(recipientID, inRealm: realm) {
|
||||
newConversation.withFriend = withFriend
|
||||
}
|
||||
|
||||
} else {
|
||||
newConversation.type = ConversationType.Group.rawValue
|
||||
|
||||
if let withGroup = groupWithGroupID(recipientID, inRealm: realm) {
|
||||
newConversation.withGroup = withGroup
|
||||
}
|
||||
}
|
||||
|
||||
conversation = newConversation
|
||||
}
|
||||
|
||||
if let conversation = conversation {
|
||||
conversation.updatedUnixTime = message.createdUnixTime // 关键哦
|
||||
message.conversation = conversation
|
||||
|
||||
tryCreateSectionDateMessageInConversation(conversation, beforeMessage: message, inRealm: realm) { sectionDateMessage in
|
||||
realm.add(sectionDateMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
realm.commitWrite()
|
||||
|
||||
|
||||
var messageInfo: JSONDictionary = [
|
||||
"recipient_id": recipientID,
|
||||
@@ -1765,24 +1765,24 @@ func createAndSendMessageWithMediaType(mediaType: MessageMediaType, inFilePath f
|
||||
messageInfo = fillMoreInfo(messageInfo)
|
||||
}
|
||||
|
||||
realm.beginWrite()
|
||||
|
||||
if let textContent = messageInfo["text_content"] as? String {
|
||||
message.textContent = textContent
|
||||
let _ = try? realm.write {
|
||||
|
||||
if let textContent = messageInfo["text_content"] as? String {
|
||||
message.textContent = textContent
|
||||
}
|
||||
|
||||
if let
|
||||
longitude = messageInfo["longitude"] as? Double,
|
||||
latitude = messageInfo["latitude"] as? Double {
|
||||
|
||||
let coordinate = Coordinate()
|
||||
coordinate.safeConfigureWithLatitude(latitude, longitude: longitude)
|
||||
|
||||
message.coordinate = coordinate
|
||||
}
|
||||
}
|
||||
|
||||
if let
|
||||
longitude = messageInfo["longitude"] as? Double,
|
||||
latitude = messageInfo["latitude"] as? Double {
|
||||
|
||||
let coordinate = Coordinate()
|
||||
coordinate.safeConfigureWithLatitude(latitude, longitude: longitude)
|
||||
|
||||
message.coordinate = coordinate
|
||||
}
|
||||
|
||||
realm.commitWrite()
|
||||
|
||||
|
||||
// 发出之前就显示 Message
|
||||
afterCreatedMessage(message)
|
||||
@@ -1796,7 +1796,7 @@ func createAndSendMessageWithMediaType(mediaType: MessageMediaType, inFilePath f
|
||||
|
||||
let realm = message.realm
|
||||
|
||||
realm?.write {
|
||||
let _ = try? realm?.write {
|
||||
message.sendState = MessageSendState.Failed.rawValue
|
||||
}
|
||||
|
||||
@@ -1832,7 +1832,7 @@ func sendMessage(message: Message, inFilePath filePath: String?, orFileData file
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = message.realm
|
||||
realm?.write {
|
||||
let _ = try? realm?.write {
|
||||
message.messageID = messageID
|
||||
message.sendState = MessageSendState.Successed.rawValue
|
||||
}
|
||||
@@ -1877,7 +1877,7 @@ func sendMessage(message: Message, inFilePath filePath: String?, orFileData file
|
||||
createMessageWithMessageInfo(messageInfo, failureHandler: failureHandler, completion: { messageID in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = message.realm
|
||||
realm?.write {
|
||||
let _ = try? realm?.write {
|
||||
message.messageID = messageID
|
||||
message.sendState = MessageSendState.Successed.rawValue
|
||||
}
|
||||
@@ -1959,7 +1959,7 @@ func resendMessage(message: Message, failureHandler: ((Reason, String?) -> Void)
|
||||
|
||||
let realm = message.realm
|
||||
|
||||
realm?.write {
|
||||
let _ = try? realm?.write {
|
||||
message.sendState = MessageSendState.NotSend.rawValue
|
||||
}
|
||||
|
||||
@@ -1976,7 +1976,7 @@ func resendMessage(message: Message, failureHandler: ((Reason, String?) -> Void)
|
||||
|
||||
let realm = message.realm
|
||||
|
||||
realm?.write {
|
||||
let _ = try? realm?.write {
|
||||
message.sendState = MessageSendState.Failed.rawValue
|
||||
}
|
||||
|
||||
|
||||
+142
-136
@@ -172,7 +172,9 @@ func syncMyInfoAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
|
||||
if let myUserID = YepUserDefaults.userID.value {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
var me = userWithUserID(myUserID, inRealm: realm)
|
||||
|
||||
@@ -186,9 +188,9 @@ func syncMyInfoAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
newUser.createdUnixTime = createdUnixTime
|
||||
}
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newUser)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newUser)
|
||||
}
|
||||
|
||||
me = newUser
|
||||
}
|
||||
@@ -213,7 +215,7 @@ func syncMyInfoAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
let _userDoNotDisturb = UserDoNotDisturb()
|
||||
_userDoNotDisturb.isOn = true
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.doNotDisturb = _userDoNotDisturb
|
||||
}
|
||||
|
||||
@@ -239,13 +241,13 @@ func syncMyInfoAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
return (localHour, localMinute)
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
|
||||
let fromParts = fromString.componentsSeparatedByString(":")
|
||||
|
||||
if let
|
||||
fromHourString = fromParts[safe: 0], fromHour = fromHourString.toInt(),
|
||||
fromMinuteString = fromParts[safe: 1], fromMinute = fromMinuteString.toInt() {
|
||||
fromHourString = fromParts[safe: 0], fromHour = Int(fromHourString),
|
||||
fromMinuteString = fromParts[safe: 1], fromMinute = Int(fromMinuteString) {
|
||||
|
||||
(userDoNotDisturb.fromHour, userDoNotDisturb.fromMinute) = convert(fromHour, fromMinute)
|
||||
}
|
||||
@@ -253,8 +255,8 @@ func syncMyInfoAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
let toParts = toString.componentsSeparatedByString(":")
|
||||
|
||||
if let
|
||||
toHourString = toParts[safe: 0], toHour = toHourString.toInt(),
|
||||
toMinuteString = toParts[safe: 1], toMinute = toMinuteString.toInt() {
|
||||
toHourString = toParts[safe: 0], toHour = Int(toHourString),
|
||||
toMinuteString = toParts[safe: 1], toMinute = Int(toMinuteString) {
|
||||
|
||||
(userDoNotDisturb.toHour, userDoNotDisturb.toMinute) = convert(toHour, toMinute)
|
||||
}
|
||||
@@ -321,7 +323,9 @@ func syncFriendshipsAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
|
||||
// 改变没有 friendship 的 user 的状态
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
let localUsers = realm.objects(User)
|
||||
|
||||
@@ -330,22 +334,21 @@ func syncFriendshipsAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
|
||||
if !remoteUerIDSet.contains(localUser.userID) {
|
||||
|
||||
realm.beginWrite()
|
||||
let _ = try? realm.write {
|
||||
|
||||
localUser.friendshipID = ""
|
||||
localUser.friendshipID = ""
|
||||
|
||||
if let myUserID = YepUserDefaults.userID.value {
|
||||
if myUserID == localUser.userID {
|
||||
localUser.friendState = UserFriendState.Me.rawValue
|
||||
if let myUserID = YepUserDefaults.userID.value {
|
||||
if myUserID == localUser.userID {
|
||||
localUser.friendState = UserFriendState.Me.rawValue
|
||||
|
||||
} else if localUser.friendState == UserFriendState.Normal.rawValue {
|
||||
localUser.friendState = UserFriendState.Stranger.rawValue
|
||||
} else if localUser.friendState == UserFriendState.Normal.rawValue {
|
||||
localUser.friendState = UserFriendState.Stranger.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
localUser.isBestfriend = false
|
||||
}
|
||||
|
||||
localUser.isBestfriend = false
|
||||
|
||||
realm.commitWrite()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,9 +367,9 @@ func syncFriendshipsAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
newUser.createdUnixTime = createdUnixTime
|
||||
}
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newUser)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newUser)
|
||||
}
|
||||
|
||||
user = newUser
|
||||
}
|
||||
@@ -377,7 +380,7 @@ func syncFriendshipsAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
|
||||
updateUserWithUserID(user.userID, useUserInfo: friendInfo)
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
|
||||
if let friendshipID = friendshipInfo["id"] as? String {
|
||||
user.friendshipID = friendshipID
|
||||
@@ -421,26 +424,27 @@ func syncGroupsAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
|
||||
// 在本地去除远端没有的 Group
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
let localGroups = realm.objects(Group)
|
||||
|
||||
realm.beginWrite()
|
||||
let _ = try? realm.write {
|
||||
|
||||
var groupsToDelete = [Group]()
|
||||
for i in 0..<localGroups.count {
|
||||
let localGroup = localGroups[i]
|
||||
var groupsToDelete = [Group]()
|
||||
for i in 0..<localGroups.count {
|
||||
let localGroup = localGroups[i]
|
||||
|
||||
if !remoteGroupIDSet.contains(localGroup.groupID) {
|
||||
groupsToDelete.append(localGroup)
|
||||
if !remoteGroupIDSet.contains(localGroup.groupID) {
|
||||
groupsToDelete.append(localGroup)
|
||||
}
|
||||
}
|
||||
for group in groupsToDelete {
|
||||
realm.delete(group)
|
||||
// TODO: 级联删除关联的数据对象
|
||||
}
|
||||
}
|
||||
for group in groupsToDelete {
|
||||
realm.delete(group)
|
||||
// TODO: 级联删除关联的数据对象
|
||||
}
|
||||
|
||||
realm.commitWrite()
|
||||
|
||||
// 增加本地没有的 Group
|
||||
|
||||
@@ -466,9 +470,9 @@ private func syncGroupWithGroupInfo(groupInfo: JSONDictionary, inRealm realm: Re
|
||||
newGroup.groupName = groupName
|
||||
}
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newGroup)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newGroup)
|
||||
}
|
||||
|
||||
group = newGroup
|
||||
}
|
||||
@@ -480,9 +484,9 @@ private func syncGroupWithGroupInfo(groupInfo: JSONDictionary, inRealm realm: Re
|
||||
conversation.type = ConversationType.Group.rawValue
|
||||
conversation.withGroup = group
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(conversation)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(conversation)
|
||||
}
|
||||
}
|
||||
|
||||
// Group Owner
|
||||
@@ -510,10 +514,10 @@ private func syncGroupWithGroupInfo(groupInfo: JSONDictionary, inRealm realm: Re
|
||||
newUser.friendState = UserFriendState.Stranger.rawValue
|
||||
}
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newUser)
|
||||
realm.commitWrite()
|
||||
|
||||
let _ = try? realm.write {
|
||||
realm.add(newUser)
|
||||
}
|
||||
|
||||
owner = newUser
|
||||
}
|
||||
|
||||
@@ -523,7 +527,7 @@ private func syncGroupWithGroupInfo(groupInfo: JSONDictionary, inRealm realm: Re
|
||||
|
||||
updateUserWithUserID(owner.userID, useUserInfo: ownerInfo)
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
group.owner = owner
|
||||
}
|
||||
}
|
||||
@@ -544,7 +548,7 @@ private func syncGroupWithGroupInfo(groupInfo: JSONDictionary, inRealm realm: Re
|
||||
|
||||
// 去除远端没有的 member
|
||||
|
||||
for (index, member) in enumerate(localMembers) {
|
||||
for (index, member) in localMembers.enumerate() {
|
||||
let user = member
|
||||
if !memberIDSet.contains(user.userID) {
|
||||
localMembers.removeAtIndex(index)
|
||||
@@ -578,7 +582,7 @@ private func syncGroupWithGroupInfo(groupInfo: JSONDictionary, inRealm realm: Re
|
||||
newMember.friendState = UserFriendState.Stranger.rawValue
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newMember)
|
||||
|
||||
localMembers.append(newMember)
|
||||
@@ -596,9 +600,9 @@ private func syncGroupWithGroupInfo(groupInfo: JSONDictionary, inRealm realm: Re
|
||||
}
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
group.members.removeAll()
|
||||
group.members.extend(localMembers)
|
||||
group.members.appendContentsOf(localMembers)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -614,7 +618,9 @@ func syncUnreadMessagesAndDoFurtherAction(furtherAction: (messageIDs: [String])
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
var messageIDs = [String]()
|
||||
|
||||
@@ -637,7 +643,9 @@ func syncMessagesReadStatus() {
|
||||
}, completion: { messagesDictionary in
|
||||
|
||||
if let messageIDs = messagesDictionary["message_ids"] as? [String] {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
var messages = messagesUnreadSentByMe(inRealm: realm)
|
||||
|
||||
var toMarkMessages = [Message]()
|
||||
@@ -659,14 +667,12 @@ func syncMessagesReadStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
for message in toMarkMessages {
|
||||
message.sendState = MessageSendState.Read.rawValue
|
||||
message.readed = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -675,75 +681,74 @@ func recordMessageWithMessageID(messageID: String, detailInfo messageInfo: JSOND
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
|
||||
realm.beginWrite()
|
||||
let _ = try? realm.write {
|
||||
|
||||
if let textContent = messageInfo["text_content"] as? String {
|
||||
message.textContent = textContent
|
||||
}
|
||||
|
||||
if let
|
||||
longitude = messageInfo["longitude"] as? Double,
|
||||
latitude = messageInfo["latitude"] as? Double {
|
||||
|
||||
let coordinate = Coordinate()
|
||||
coordinate.safeConfigureWithLatitude(latitude, longitude: longitude)
|
||||
|
||||
message.coordinate = coordinate
|
||||
}
|
||||
|
||||
if let attachments = messageInfo["attachments"] as? [JSONDictionary] {
|
||||
|
||||
for attachmentInfo in attachments {
|
||||
|
||||
// S3: normal file
|
||||
if let
|
||||
normalFileInfo = attachmentInfo["file"] as? JSONDictionary,
|
||||
fileURLString = normalFileInfo["url"] as? String,
|
||||
kind = attachmentInfo["kind"] as? String {
|
||||
if kind == "thumbnail" {
|
||||
message.thumbnailURLString = fileURLString
|
||||
} else {
|
||||
message.attachmentURLString = fileURLString
|
||||
}
|
||||
}
|
||||
|
||||
if let metaDataString = attachmentInfo["metadata"] as? String {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
if let textContent = messageInfo["text_content"] as? String {
|
||||
message.textContent = textContent
|
||||
}
|
||||
|
||||
if let mediaType = messageInfo["media_type"] as? String {
|
||||
if let
|
||||
longitude = messageInfo["longitude"] as? Double,
|
||||
latitude = messageInfo["latitude"] as? Double {
|
||||
|
||||
switch mediaType {
|
||||
case MessageMediaType.Text.description:
|
||||
message.mediaType = MessageMediaType.Text.rawValue
|
||||
case MessageMediaType.Image.description:
|
||||
message.mediaType = MessageMediaType.Image.rawValue
|
||||
case MessageMediaType.Video.description:
|
||||
message.mediaType = MessageMediaType.Video.rawValue
|
||||
case MessageMediaType.Audio.description:
|
||||
message.mediaType = MessageMediaType.Audio.rawValue
|
||||
case MessageMediaType.Sticker.description:
|
||||
message.mediaType = MessageMediaType.Sticker.rawValue
|
||||
case MessageMediaType.Location.description:
|
||||
message.mediaType = MessageMediaType.Location.rawValue
|
||||
default:
|
||||
break
|
||||
let coordinate = Coordinate()
|
||||
coordinate.safeConfigureWithLatitude(latitude, longitude: longitude)
|
||||
|
||||
message.coordinate = coordinate
|
||||
}
|
||||
|
||||
if let attachments = messageInfo["attachments"] as? [JSONDictionary] {
|
||||
|
||||
for attachmentInfo in attachments {
|
||||
|
||||
// S3: normal file
|
||||
if let
|
||||
normalFileInfo = attachmentInfo["file"] as? JSONDictionary,
|
||||
fileURLString = normalFileInfo["url"] as? String,
|
||||
kind = attachmentInfo["kind"] as? String {
|
||||
if kind == "thumbnail" {
|
||||
message.thumbnailURLString = fileURLString
|
||||
} else {
|
||||
message.attachmentURLString = fileURLString
|
||||
}
|
||||
}
|
||||
|
||||
if let metaDataString = attachmentInfo["metadata"] as? String {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
}
|
||||
|
||||
if let mediaType = messageInfo["media_type"] as? String {
|
||||
|
||||
switch mediaType {
|
||||
case MessageMediaType.Text.description:
|
||||
message.mediaType = MessageMediaType.Text.rawValue
|
||||
case MessageMediaType.Image.description:
|
||||
message.mediaType = MessageMediaType.Image.rawValue
|
||||
case MessageMediaType.Video.description:
|
||||
message.mediaType = MessageMediaType.Video.rawValue
|
||||
case MessageMediaType.Audio.description:
|
||||
message.mediaType = MessageMediaType.Audio.rawValue
|
||||
case MessageMediaType.Sticker.description:
|
||||
message.mediaType = MessageMediaType.Sticker.rawValue
|
||||
case MessageMediaType.Location.description:
|
||||
message.mediaType = MessageMediaType.Location.rawValue
|
||||
default:
|
||||
break
|
||||
}
|
||||
// TODO: 若有更多的 Media Type
|
||||
}
|
||||
// TODO: 若有更多的 Media Type
|
||||
}
|
||||
}
|
||||
|
||||
realm.commitWrite()
|
||||
}
|
||||
}
|
||||
|
||||
func syncMessageWithMessageInfo(messageInfo: JSONDictionary, inRealm realm: Realm, andDoFurtherAction furtherAction: ((messageIDs: [String]) -> Void)? ) {
|
||||
|
||||
func deleteMessage(message: Message, inRealm realm: Realm) {
|
||||
realm.beginWrite()
|
||||
realm.delete(message)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.delete(message)
|
||||
}
|
||||
}
|
||||
|
||||
if let messageID = messageInfo["id"] as? String {
|
||||
@@ -767,7 +772,7 @@ func syncMessageWithMessageInfo(messageInfo: JSONDictionary, inRealm realm: Real
|
||||
}
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.add(newMessage)
|
||||
}
|
||||
|
||||
@@ -799,9 +804,9 @@ func syncMessageWithMessageInfo(messageInfo: JSONDictionary, inRealm realm: Real
|
||||
|
||||
newUser.friendState = UserFriendState.Stranger.rawValue
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newUser)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newUser)
|
||||
}
|
||||
|
||||
sender = newUser
|
||||
}
|
||||
@@ -810,7 +815,7 @@ func syncMessageWithMessageInfo(messageInfo: JSONDictionary, inRealm realm: Real
|
||||
|
||||
updateUserWithUserID(sender.userID, useUserInfo: senderInfo)
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.fromFriend = sender
|
||||
}
|
||||
|
||||
@@ -833,9 +838,9 @@ func syncMessageWithMessageInfo(messageInfo: JSONDictionary, inRealm realm: Real
|
||||
}
|
||||
}
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newGroup)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newGroup)
|
||||
}
|
||||
|
||||
sendFromGroup = newGroup
|
||||
}
|
||||
@@ -866,9 +871,9 @@ func syncMessageWithMessageInfo(messageInfo: JSONDictionary, inRealm realm: Real
|
||||
newConversation.withFriend = sender
|
||||
}
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newConversation)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newConversation)
|
||||
}
|
||||
|
||||
conversation = newConversation
|
||||
}
|
||||
@@ -876,19 +881,20 @@ func syncMessageWithMessageInfo(messageInfo: JSONDictionary, inRealm realm: Real
|
||||
// 在保证有 Conversation 的情况下继续,不然消息没有必要保留
|
||||
|
||||
if let conversation = conversation {
|
||||
realm.beginWrite()
|
||||
|
||||
conversation.updatedUnixTime = message.createdUnixTime
|
||||
|
||||
message.conversation = conversation
|
||||
|
||||
var sectionDateMessageID: String?
|
||||
tryCreateSectionDateMessageInConversation(conversation, beforeMessage: message, inRealm: realm) { sectionDateMessage in
|
||||
realm.add(sectionDateMessage)
|
||||
sectionDateMessageID = sectionDateMessage.messageID
|
||||
}
|
||||
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
|
||||
conversation.updatedUnixTime = message.createdUnixTime
|
||||
|
||||
message.conversation = conversation
|
||||
|
||||
tryCreateSectionDateMessageInConversation(conversation, beforeMessage: message, inRealm: realm) { sectionDateMessage in
|
||||
realm.add(sectionDateMessage)
|
||||
sectionDateMessageID = sectionDateMessage.messageID
|
||||
}
|
||||
}
|
||||
|
||||
// 纪录消息的 detail 信息
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ struct S3UploadParams {
|
||||
|
||||
private func uploadFileToS3(inFilePath filePath: String?, orFileData fileData: NSData?, mimeType: String, s3UploadParams: S3UploadParams, failureHandler: ((Reason, String?) -> ())?, completion: () -> Void) {
|
||||
|
||||
let parameters = [
|
||||
let parameters: [NSObject: AnyObject] = [
|
||||
"key": s3UploadParams.key,
|
||||
"acl": s3UploadParams.acl,
|
||||
"X-Amz-Algorithm": s3UploadParams.algorithm,
|
||||
@@ -51,16 +51,18 @@ private func uploadFileToS3(inFilePath filePath: String?, orFileData fileData: N
|
||||
|
||||
let filename = "attachment"
|
||||
|
||||
let request = AFHTTPRequestSerializer().multipartFormRequestWithMethod("POST", URLString: s3UploadParams.url, parameters: parameters, constructingBodyWithBlock: { formData in
|
||||
guard let request = try? AFHTTPRequestSerializer().multipartFormRequestWithMethod("POST", URLString: s3UploadParams.url, parameters: parameters, constructingBodyWithBlock: { formData in
|
||||
|
||||
if let filePath = filePath {
|
||||
formData.appendPartWithFileURL(NSURL(fileURLWithPath: filePath)!, name: "file", fileName: filename, mimeType: mimeType, error: nil)
|
||||
let _ = try? formData.appendPartWithFileURL(NSURL(fileURLWithPath: filePath), name: "file", fileName: filename, mimeType: mimeType)
|
||||
|
||||
} else if let fileData = fileData {
|
||||
formData.appendPartWithFileData(fileData, name: "file", fileName: filename, mimeType: mimeType)
|
||||
}
|
||||
|
||||
}, error: nil)
|
||||
}, error: ()) else {
|
||||
failureHandler?(.Other(nil), "Can not create AFHTTPRequestSerializer request")
|
||||
return
|
||||
}
|
||||
|
||||
let manager = AFURLSessionManager(sessionConfiguration: NSURLSessionConfiguration.defaultSessionConfiguration())
|
||||
manager.responseSerializer = AFHTTPResponseSerializer()
|
||||
|
||||
@@ -25,7 +25,7 @@ class AboutViewController: UIViewController {
|
||||
|
||||
let aboutCellID = "AboutCell"
|
||||
|
||||
let rowHeight: CGFloat = Ruler.match(.iPhoneHeights(50, 60, 60, 60))
|
||||
let rowHeight: CGFloat = Ruler.iPhoneVertical(50, 60, 60, 60).value
|
||||
|
||||
let aboutAnnotations: [String] = [
|
||||
NSLocalizedString("Pods help Yep", comment: ""),
|
||||
@@ -38,8 +38,8 @@ class AboutViewController: UIViewController {
|
||||
|
||||
title = NSLocalizedString("About", comment: "")
|
||||
|
||||
appLogoImageViewTopConstraint.constant = Ruler.match(.iPhoneHeights(0, 20, 40, 60))
|
||||
appNameLabelTopConstraint.constant = Ruler.match(.iPhoneHeights(10, 20, 20, 20))
|
||||
appLogoImageViewTopConstraint.constant = Ruler.iPhoneVertical(0, 20, 40, 60).value
|
||||
appNameLabelTopConstraint.constant = Ruler.iPhoneVertical(10, 20, 20, 20).value
|
||||
|
||||
appNameLabel.textColor = UIColor.yepTintColor()
|
||||
|
||||
|
||||
@@ -102,10 +102,12 @@ extension BlackListViewController: UITableViewDataSource, UITableViewDelegate {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let user = userWithUserID(discoveredUser.id, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.blocked = false
|
||||
}
|
||||
}
|
||||
@@ -124,7 +126,7 @@ extension BlackListViewController: UITableViewDataSource, UITableViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String! {
|
||||
func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? {
|
||||
return NSLocalizedString("Unblock", comment: "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class ContactsViewController: BaseViewController {
|
||||
|
||||
// 超过一定人数才显示搜索框
|
||||
|
||||
if friends.count > Int(Ruler.match(.iPhoneHeights(6, 8, 10, 12))) {
|
||||
if friends.count > Ruler.iPhoneVertical(6, 8, 10, 12).value {
|
||||
|
||||
let searchController = UISearchController(searchResultsController: nil)
|
||||
searchController.delegate = self
|
||||
@@ -194,7 +194,10 @@ extension ContactsViewController: UISearchResultsUpdating {
|
||||
|
||||
func updateSearchResultsForSearchController(searchController: UISearchController) {
|
||||
|
||||
let searchText = searchController.searchBar.text
|
||||
guard let searchText = searchController.searchBar.text else {
|
||||
return
|
||||
}
|
||||
|
||||
let predicate = NSPredicate(format: "nickname CONTAINS[c] %@", searchText)
|
||||
filteredFriends = friends.filter(predicate)
|
||||
|
||||
|
||||
@@ -24,16 +24,14 @@ class ConversationLayout: UICollectionViewFlowLayout {
|
||||
|
||||
var insertIndexPathSet = Set<NSIndexPath>()
|
||||
|
||||
if let updateItems = updateItems as? [UICollectionViewUpdateItem] {
|
||||
for updateItem in updateItems {
|
||||
switch updateItem.updateAction {
|
||||
case .Insert:
|
||||
if let indexPath = updateItem.indexPathAfterUpdate {
|
||||
insertIndexPathSet.insert(indexPath)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
for updateItem in updateItems {
|
||||
switch updateItem.updateAction {
|
||||
case .Insert:
|
||||
let indexPath = updateItem.indexPathAfterUpdate
|
||||
insertIndexPathSet.insert(indexPath)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +43,7 @@ class ConversationLayout: UICollectionViewFlowLayout {
|
||||
let attributes = layoutAttributesForItemAtIndexPath(itemIndexPath)
|
||||
|
||||
if insertIndexPathSet.contains(itemIndexPath) {
|
||||
attributes.frame.origin.y += 30
|
||||
attributes?.frame.origin.y += 30
|
||||
|
||||
insertIndexPathSet.remove(itemIndexPath)
|
||||
}
|
||||
|
||||
+7
-7
@@ -82,10 +82,10 @@ class ConversationMessagePreviewNavigationControllerDelegate: NSObject, UINaviga
|
||||
let largerOffset: CGFloat = 0//80
|
||||
|
||||
func presentTransition(transitionContext: UIViewControllerContextTransitioning) {
|
||||
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? ConversationsViewController
|
||||
//let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? ConversationsViewController
|
||||
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as? MessageMediaViewController
|
||||
|
||||
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
|
||||
//let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
|
||||
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)
|
||||
|
||||
let containerView = transitionContext.containerView()
|
||||
@@ -97,7 +97,7 @@ class ConversationMessagePreviewNavigationControllerDelegate: NSObject, UINaviga
|
||||
transitionViewCover.backgroundColor = UIColor.whiteColor()
|
||||
snapshot.addSubview(transitionViewCover)
|
||||
|
||||
containerView.addSubview(snapshot)
|
||||
containerView?.addSubview(snapshot)
|
||||
}
|
||||
|
||||
// let blackColorView = UIView()
|
||||
@@ -106,7 +106,7 @@ class ConversationMessagePreviewNavigationControllerDelegate: NSObject, UINaviga
|
||||
// blackColorView.alpha = 0
|
||||
// containerView.addSubview(blackColorView)
|
||||
|
||||
containerView.addSubview(toView!)
|
||||
containerView?.addSubview(toView!)
|
||||
|
||||
let animatingVC = toVC!
|
||||
let animatingView = toView!
|
||||
@@ -202,14 +202,14 @@ class ConversationMessagePreviewNavigationControllerDelegate: NSObject, UINaviga
|
||||
|
||||
let containerView = transitionContext.containerView()
|
||||
|
||||
containerView.addSubview(toView!)
|
||||
containerView?.addSubview(toView!)
|
||||
|
||||
if let snapshot = snapshot {
|
||||
snapshot.alpha = 1
|
||||
containerView.addSubview(snapshot)
|
||||
containerView?.addSubview(snapshot)
|
||||
}
|
||||
|
||||
containerView.addSubview(fromView!)
|
||||
containerView?.addSubview(fromView!)
|
||||
|
||||
let animatingVC = fromVC!
|
||||
let animatingView = fromView!
|
||||
|
||||
@@ -60,15 +60,15 @@ class ConversationMessagePreviewTransitionManager: NSObject, UIViewControllerTra
|
||||
let largerOffset: CGFloat = 80
|
||||
|
||||
func presentTransition(transitionContext: UIViewControllerContextTransitioning) {
|
||||
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? ConversationsViewController
|
||||
//let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? ConversationsViewController
|
||||
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as? MessageMediaViewController
|
||||
|
||||
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
|
||||
//let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
|
||||
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)
|
||||
|
||||
let containerView = transitionContext.containerView()
|
||||
|
||||
containerView.addSubview(toView!)
|
||||
containerView?.addSubview(toView!)
|
||||
|
||||
let animatingVC = toVC!
|
||||
let animatingView = toView!
|
||||
|
||||
@@ -70,7 +70,7 @@ class ConversationViewController: BaseViewController {
|
||||
return titleView
|
||||
}()
|
||||
|
||||
lazy var moreView = ConversationMoreView()
|
||||
lazy var moreView: ConversationMoreView = ConversationMoreView()
|
||||
|
||||
lazy var pullToRefreshView: PullToRefreshView = {
|
||||
|
||||
@@ -163,7 +163,7 @@ class ConversationViewController: BaseViewController {
|
||||
lazy var imagePicker: UIImagePickerController = {
|
||||
let imagePicker = UIImagePickerController()
|
||||
imagePicker.delegate = self
|
||||
imagePicker.mediaTypes = [kUTTypeImage, kUTTypeMovie]
|
||||
imagePicker.mediaTypes = [kUTTypeImage as String, kUTTypeMovie as String]
|
||||
imagePicker.videoQuality = .TypeMedium
|
||||
imagePicker.allowsEditing = false
|
||||
return imagePicker
|
||||
@@ -199,7 +199,7 @@ class ConversationViewController: BaseViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
realm = Realm()
|
||||
realm = try! Realm()
|
||||
|
||||
// 优先处理侧滑,而不是 scrollView 的上下滚动,避免出现你想侧滑返回的时候,结果触发了 scrollView 的上下滚动
|
||||
if let gestures = navigationController?.view.gestureRecognizers {
|
||||
@@ -212,7 +212,7 @@ class ConversationViewController: BaseViewController {
|
||||
}
|
||||
}
|
||||
|
||||
navigationController?.interactivePopGestureRecognizer.delaysTouchesBegan = false
|
||||
navigationController?.interactivePopGestureRecognizer?.delaysTouchesBegan = false
|
||||
|
||||
view.tintAdjustmentMode = .Normal
|
||||
|
||||
@@ -226,7 +226,7 @@ class ConversationViewController: BaseViewController {
|
||||
|
||||
navigationItem.titleView = titleView
|
||||
|
||||
if let withFriend = conversation?.withFriend {
|
||||
if let _ = conversation?.withFriend {
|
||||
let moreBarButtonItem = UIBarButtonItem(image: UIImage(named: "icon_more"), style: UIBarButtonItemStyle.Plain, target: self, action: "moreAction")
|
||||
navigationItem.rightBarButtonItem = moreBarButtonItem
|
||||
}
|
||||
@@ -436,7 +436,7 @@ class ConversationViewController: BaseViewController {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}).map({ self.markMessageAsReaded($0) })
|
||||
}).forEach({ self.markMessageAsReaded($0) })
|
||||
|
||||
// MARK: Notify Typing
|
||||
|
||||
@@ -572,14 +572,14 @@ class ConversationViewController: BaseViewController {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
if let realm = message.realm {
|
||||
realm.beginWrite()
|
||||
message.localAttachmentName = fileURL.path!.lastPathComponent.stringByDeletingPathExtension
|
||||
message.mediaType = MessageMediaType.Audio.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
let _ = try? realm.write {
|
||||
message.localAttachmentName = fileURL.URLByDeletingPathExtension?.lastPathComponent ?? ""
|
||||
message.mediaType = MessageMediaType.Audio.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
}
|
||||
realm.commitWrite()
|
||||
|
||||
|
||||
self?.updateConversationCollectionViewWithMessageIDs(nil, scrollToBottom: true, success: { _ in
|
||||
})
|
||||
}
|
||||
@@ -599,13 +599,13 @@ class ConversationViewController: BaseViewController {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
if let realm = message.realm {
|
||||
realm.beginWrite()
|
||||
message.localAttachmentName = fileURL.path!.lastPathComponent.stringByDeletingPathExtension
|
||||
message.mediaType = MessageMediaType.Audio.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
let _ = try? realm.write {
|
||||
message.localAttachmentName = fileURL.URLByDeletingPathExtension?.lastPathComponent ?? ""
|
||||
message.mediaType = MessageMediaType.Audio.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
}
|
||||
realm.commitWrite()
|
||||
|
||||
self?.updateConversationCollectionViewWithMessageIDs(nil, scrollToBottom: true, success: { _ in
|
||||
})
|
||||
@@ -670,7 +670,7 @@ class ConversationViewController: BaseViewController {
|
||||
}
|
||||
}
|
||||
|
||||
messageToolbar.voiceRecordEndAction = { [weak self] messageToolbar in
|
||||
messageToolbar.voiceRecordEndAction = { messageToolbar in
|
||||
|
||||
YepAudioService.sharedManager.shouldIgnoreStart = true
|
||||
|
||||
@@ -772,10 +772,12 @@ class ConversationViewController: BaseViewController {
|
||||
let messageID = message.messageID
|
||||
|
||||
dispatch_async(realmQueue) {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
message.readed = true
|
||||
}
|
||||
|
||||
@@ -940,9 +942,11 @@ class ConversationViewController: BaseViewController {
|
||||
println("friendRequestState: \(friendRequestState.rawValue)")
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
if let user = userWithUserID(userID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.friendState = UserFriendState.IssuedRequest.rawValue
|
||||
}
|
||||
}
|
||||
@@ -964,9 +968,11 @@ class ConversationViewController: BaseViewController {
|
||||
println("acceptFriendRequestWithID: \(friendRequestID), \(success)")
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
if let user = userWithUserID(userID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.friendState = UserFriendState.Normal.rawValue
|
||||
}
|
||||
}
|
||||
@@ -1278,10 +1284,13 @@ class ConversationViewController: BaseViewController {
|
||||
}
|
||||
|
||||
func updateNotificationEnabled(enabled: Bool, forUserWithUserID userID: String) {
|
||||
let realm = Realm()
|
||||
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let user = userWithUserID(userID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.notificationEnabled = enabled
|
||||
}
|
||||
|
||||
@@ -1365,10 +1374,13 @@ class ConversationViewController: BaseViewController {
|
||||
}
|
||||
|
||||
func updateBlocked(blocked: Bool, forUserWithUserID userID: String, needUpdateUI: Bool = true) {
|
||||
let realm = Realm()
|
||||
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let user = userWithUserID(userID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
user.blocked = blocked
|
||||
}
|
||||
|
||||
@@ -1485,13 +1497,7 @@ class ConversationViewController: BaseViewController {
|
||||
return
|
||||
}
|
||||
|
||||
var newMessagesCount = Int(messages.count - _lastTimeMessagesCount)
|
||||
|
||||
/*
|
||||
if let messageIDs = messageIDs {
|
||||
newMessagesCount = messageIDs.count
|
||||
}
|
||||
*/
|
||||
let newMessagesCount = Int(messages.count - _lastTimeMessagesCount)
|
||||
|
||||
let lastDisplayedMessagesRange = displayedMessagesRange
|
||||
|
||||
@@ -1518,8 +1524,8 @@ class ConversationViewController: BaseViewController {
|
||||
for messageID in messageIDs {
|
||||
if let
|
||||
message = messageWithMessageID(messageID, inRealm: realm),
|
||||
index = messages.indexOf(message),
|
||||
indexPath = NSIndexPath(forItem: index - displayedMessagesRange.location, inSection: 0) {
|
||||
index = messages.indexOf(message) {
|
||||
let indexPath = NSIndexPath(forItem: index - displayedMessagesRange.location, inSection: 0)
|
||||
println("insert item: \(indexPath.item)")
|
||||
|
||||
indexPaths.append(indexPath)
|
||||
@@ -2137,7 +2143,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
|
||||
if let cell = cell as? ChatLeftLocationCell {
|
||||
|
||||
cell.configureWithMessage(message, mediaTapAction: { [weak self] in
|
||||
cell.configureWithMessage(message, mediaTapAction: {
|
||||
if let coordinate = message.coordinate {
|
||||
let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
|
||||
let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil))
|
||||
@@ -2175,7 +2181,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend image?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
|
||||
|
||||
resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepAlert.alertSorry(message: NSLocalizedString("Failed to resend image!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
|
||||
|
||||
@@ -2213,7 +2219,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend audio?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
|
||||
|
||||
resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepAlert.alertSorry(message: NSLocalizedString("Failed to resend audio!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
|
||||
|
||||
@@ -2243,7 +2249,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend video?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
|
||||
|
||||
resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepAlert.alertSorry(message: NSLocalizedString("Failed to resend video!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
|
||||
|
||||
@@ -2279,7 +2285,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend location?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
|
||||
|
||||
resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepAlert.alertSorry(message: NSLocalizedString("Failed to resend location!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
|
||||
|
||||
@@ -2317,7 +2323,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: {
|
||||
|
||||
resendMessage(message, failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepAlert.alertSorry(message: NSLocalizedString("Failed to resend text!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self)
|
||||
|
||||
@@ -2369,7 +2375,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
strongSelf.displayedMessagesRange.length -= 1
|
||||
}
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
if let mediaMetaData = sectionDateMessage.mediaMetaData {
|
||||
realm.delete(mediaMetaData)
|
||||
}
|
||||
@@ -2389,7 +2395,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
|
||||
} else {
|
||||
strongSelf.displayedMessagesRange.length -= 1
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
if let mediaMetaData = message.mediaMetaData {
|
||||
realm.delete(mediaMetaData)
|
||||
}
|
||||
@@ -2491,7 +2497,7 @@ extension ConversationViewController: PullToRefreshViewDelegate {
|
||||
pulllToRefreshView.endRefreshingAndDoFurtherAction() { [weak self] in
|
||||
|
||||
if let strongSelf = self {
|
||||
let lastDisplayedMessagesRange = strongSelf.displayedMessagesRange
|
||||
//let lastDisplayedMessagesRange = strongSelf.displayedMessagesRange
|
||||
|
||||
var newMessagesCount = strongSelf.messagesBunchCount
|
||||
|
||||
@@ -2554,7 +2560,7 @@ extension ConversationViewController : AVAudioRecorderDelegate {
|
||||
}
|
||||
|
||||
func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder, error: NSError?) {
|
||||
println("\(error.localizedDescription)")
|
||||
println("\(error?.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2615,7 +2621,7 @@ extension ConversationViewController: AVAudioPlayerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func audioPlayerEndInterruption(player: AVAudioPlayer!) {
|
||||
func audioPlayerEndInterruption(player: AVAudioPlayer) {
|
||||
|
||||
println("audioPlayerEndInterruption")
|
||||
}
|
||||
@@ -2631,7 +2637,7 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
|
||||
switch mediaType {
|
||||
|
||||
case kUTTypeImage as String:
|
||||
case kUTTypeImage as! String:
|
||||
|
||||
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
|
||||
|
||||
@@ -2658,7 +2664,7 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
}
|
||||
}
|
||||
|
||||
case kUTTypeMovie as String:
|
||||
case kUTTypeMovie as! String:
|
||||
|
||||
if let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL {
|
||||
println("videoURL \(videoURL)")
|
||||
@@ -2698,7 +2704,7 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
|
||||
let data = UIImageJPEGRepresentation(blurredThumbnail, 0.7)
|
||||
|
||||
let string = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(0))
|
||||
let string = data!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
|
||||
|
||||
print("image blurredThumbnail string length: \(string.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))\n")
|
||||
|
||||
@@ -2724,7 +2730,7 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
|
||||
// Do send
|
||||
|
||||
let imageData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality())
|
||||
let imageData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality())!
|
||||
|
||||
let messageImageName = NSUUID().UUIDString
|
||||
|
||||
@@ -2734,15 +2740,15 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
if let messageImageURL = NSFileManager.saveMessageImageData(imageData, withName: messageImageName) {
|
||||
if let _ = NSFileManager.saveMessageImageData(imageData, withName: messageImageName) {
|
||||
if let realm = message.realm {
|
||||
realm.beginWrite()
|
||||
message.localAttachmentName = messageImageName
|
||||
message.mediaType = MessageMediaType.Image.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
let _ = try? realm.write {
|
||||
message.localAttachmentName = messageImageName
|
||||
message.mediaType = MessageMediaType.Image.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
}
|
||||
realm.commitWrite()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2764,15 +2770,15 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
sendImageInFilePath(nil, orFileData: imageData, metaData: nil, toRecipient: withGroup.groupID, recipientType: "Circle", afterCreatedMessage: { [weak self] message in
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
if let messageImageURL = NSFileManager.saveMessageImageData(imageData, withName: messageImageName) {
|
||||
if let _ = NSFileManager.saveMessageImageData(imageData, withName: messageImageName) {
|
||||
if let realm = message.realm {
|
||||
realm.beginWrite()
|
||||
message.localAttachmentName = messageImageName
|
||||
message.mediaType = MessageMediaType.Image.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
let _ = try? realm.write {
|
||||
message.localAttachmentName = messageImageName
|
||||
message.mediaType = MessageMediaType.Image.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
}
|
||||
realm.commitWrite()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2820,9 +2826,9 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
if let thumbnail = image.resizeToSize(CGSize(width: thumbnailWidth, height: thumbnailHeight), withInterpolationQuality: CGInterpolationQuality.Low) {
|
||||
let blurredThumbnail = thumbnail.blurredImageWithRadius(5, iterations: 7, tintColor: UIColor.clearColor())
|
||||
|
||||
let data = UIImageJPEGRepresentation(blurredThumbnail, 0.7)
|
||||
let data = UIImageJPEGRepresentation(blurredThumbnail, 0.7)!
|
||||
|
||||
let string = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(0))
|
||||
let string = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
|
||||
|
||||
print("video blurredThumbnail string length: \(string.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))\n")
|
||||
|
||||
@@ -2855,23 +2861,23 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
|
||||
if let videoData = NSData(contentsOfURL: videoURL) {
|
||||
|
||||
if let messageVideoURL = NSFileManager.saveMessageVideoData(videoData, withName: messageVideoName) {
|
||||
if let _ = NSFileManager.saveMessageVideoData(videoData, withName: messageVideoName) {
|
||||
if let realm = message.realm {
|
||||
realm.beginWrite()
|
||||
let _ = try? realm.write {
|
||||
|
||||
if let thumbnailData = thumbnailData {
|
||||
if let thumbnailURL = NSFileManager.saveMessageImageData(thumbnailData, withName: messageVideoName) {
|
||||
message.localThumbnailName = messageVideoName
|
||||
if let thumbnailData = thumbnailData {
|
||||
if let _ = NSFileManager.saveMessageImageData(thumbnailData, withName: messageVideoName) {
|
||||
message.localThumbnailName = messageVideoName
|
||||
}
|
||||
}
|
||||
|
||||
message.localAttachmentName = messageVideoName
|
||||
|
||||
message.mediaType = MessageMediaType.Video.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
}
|
||||
|
||||
message.localAttachmentName = messageVideoName
|
||||
|
||||
message.mediaType = MessageMediaType.Video.rawValue
|
||||
if let metaDataString = metaData {
|
||||
message.mediaMetaData = mediaMetaDataFromString(metaDataString, inRealm: realm)
|
||||
}
|
||||
realm.commitWrite()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class ConversationsViewController: UIViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
realm = Realm()
|
||||
realm = try! Realm()
|
||||
|
||||
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reloadConversationsTableView", name: YepNewMessagesReceivedNotification, object: nil)
|
||||
|
||||
@@ -100,7 +100,9 @@ class ConversationsViewController: UIViewController {
|
||||
|
||||
// 每个对话的最近 10 条消息(image or thumbnail)
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
for conversation in realm.objects(Conversation) {
|
||||
|
||||
@@ -250,13 +252,13 @@ extension ConversationsViewController: UITableViewDataSource, UITableViewDelegat
|
||||
|
||||
// delete all media files of messages
|
||||
|
||||
messages.map { deleteMediaFilesOfMessage($0) }
|
||||
messages.forEach { deleteMediaFilesOfMessage($0) }
|
||||
|
||||
// delete all mediaMetaDatas
|
||||
|
||||
for message in messages {
|
||||
if let mediaMetaData = message.mediaMetaData {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(mediaMetaData)
|
||||
}
|
||||
}
|
||||
@@ -264,7 +266,7 @@ extension ConversationsViewController: UITableViewDataSource, UITableViewDelegat
|
||||
|
||||
// delete all messages in conversation
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(messages)
|
||||
}
|
||||
}
|
||||
@@ -275,7 +277,7 @@ extension ConversationsViewController: UITableViewDataSource, UITableViewDelegat
|
||||
|
||||
// delete conversation, finally
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(conversation)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class DiscoverViewController: BaseViewController {
|
||||
}
|
||||
}
|
||||
|
||||
lazy var filterView = DiscoverFilterView()
|
||||
lazy var filterView: DiscoverFilterView = DiscoverFilterView()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
@@ -85,7 +85,9 @@ class DoNotDisturbPeriodViewController: UIViewController {
|
||||
|
||||
success()
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
@@ -97,7 +99,7 @@ class DoNotDisturbPeriodViewController: UIViewController {
|
||||
let _userDoNotDisturb = UserDoNotDisturb()
|
||||
_userDoNotDisturb.isOn = true
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.doNotDisturb = _userDoNotDisturb
|
||||
}
|
||||
|
||||
@@ -105,7 +107,7 @@ class DoNotDisturbPeriodViewController: UIViewController {
|
||||
}
|
||||
|
||||
if let userDoNotDisturb = me.doNotDisturb {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
userDoNotDisturb.fromHour = self.doNotDisturbPeriod.fromHour
|
||||
userDoNotDisturb.fromMinute = self.doNotDisturbPeriod.fromMinute
|
||||
|
||||
|
||||
@@ -50,7 +50,8 @@ class EditNicknameAndBadgeViewController: UITableViewController {
|
||||
nicknameTextField.text = YepUserDefaults.nickname.value
|
||||
nicknameTextField.delegate = self
|
||||
|
||||
let gap = Ruler.match(.iPhoneWidths(10, 25, 32))
|
||||
let gap: CGFloat = Ruler.iPhoneHorizontal(10, 25, 32).value
|
||||
|
||||
centerLeft1GapConstraint.constant = gap
|
||||
centerRight1GapConstraint.constant = gap
|
||||
left1Left2GapConstraint.constant = gap
|
||||
@@ -96,11 +97,11 @@ class EditNicknameAndBadgeViewController: UITableViewController {
|
||||
techBadgeView,
|
||||
]
|
||||
|
||||
let disableAllBadges: () -> Void = {
|
||||
badgeViews.map { $0.enabled = false }
|
||||
let disableAllBadges: () -> Void = { [weak self] in
|
||||
self?.badgeViews.forEach { $0.enabled = false }
|
||||
}
|
||||
|
||||
badgeViews.map {
|
||||
badgeViews.forEach {
|
||||
|
||||
$0.tapAction = { badgeView in
|
||||
|
||||
@@ -163,7 +164,7 @@ class EditNicknameAndBadgeViewController: UITableViewController {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
if let badgeName = YepUserDefaults.badge.value {
|
||||
badgeViews.map { $0.enabled = ($0.badge.rawValue == badgeName) }
|
||||
badgeViews.forEach { $0.enabled = ($0.badge.rawValue == badgeName) }
|
||||
}
|
||||
|
||||
if let enabledBadgeView = badgeViews.filter({ $0.enabled }).first {
|
||||
@@ -180,7 +181,9 @@ extension EditNicknameAndBadgeViewController: UITextFieldDelegate {
|
||||
|
||||
textField.resignFirstResponder()
|
||||
|
||||
let newNickname = textField.text
|
||||
guard let newNickname = textField.text else {
|
||||
return true
|
||||
}
|
||||
|
||||
if newNickname.isEmpty {
|
||||
YepAlert.alertSorry(message: NSLocalizedString("You did not enter any nickname!", comment: ""), inViewController: self, withDismissAction: {
|
||||
@@ -193,7 +196,7 @@ extension EditNicknameAndBadgeViewController: UITextFieldDelegate {
|
||||
if newNickname != YepUserDefaults.nickname.value {
|
||||
|
||||
updateMyselfWithInfo(["nickname": newNickname], failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepAlert.alertSorry(message: NSLocalizedString("Update nickname failed!", comment: ""), inViewController: self)
|
||||
|
||||
|
||||
@@ -198,7 +198,8 @@ extension EditProfileViewController: UITableViewDataSource, UITableViewDelegate
|
||||
var username = ""
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: Realm()) {
|
||||
realm = try? Realm(),
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
username = me.username
|
||||
}
|
||||
|
||||
@@ -315,7 +316,7 @@ extension EditProfileViewController: UITableViewDataSource, UITableViewDelegate
|
||||
let tableViewWidth = CGRectGetWidth(editProfileTableView.bounds)
|
||||
let introLabelMaxWidth = tableViewWidth - YepConfig.EditProfile.introInset
|
||||
|
||||
let rect = introduction.boundingRectWithSize(CGSize(width: introLabelMaxWidth, height: CGFloat(FLT_MAX)), options: .UsesLineFragmentOrigin | .UsesFontLeading, attributes: introAttributes, context: nil)
|
||||
let rect = introduction.boundingRectWithSize(CGSize(width: introLabelMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: introAttributes, context: nil)
|
||||
|
||||
let height = 20 + 22 + 10 + ceil(rect.height) + 20
|
||||
|
||||
@@ -347,7 +348,7 @@ extension EditProfileViewController: UITableViewDataSource, UITableViewDelegate
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: Realm()) {
|
||||
me = userWithUserID(myUserID, inRealm: try! Realm()) {
|
||||
|
||||
let username = me.username
|
||||
|
||||
@@ -364,11 +365,14 @@ extension EditProfileViewController: UITableViewDataSource, UITableViewDelegate
|
||||
|
||||
}, completion: { success in
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak tableView] in
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.username = newUsername
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class EditSkillsViewController: BaseViewController {
|
||||
skillsTableView.rowHeight = 60
|
||||
|
||||
var separatorInset = skillsTableView.separatorInset
|
||||
separatorInset.left = Ruler.match(.iPhoneWidths(15, 20, 25))
|
||||
separatorInset.left = Ruler.iPhoneHorizontal(15, 20, 25).value
|
||||
skillsTableView.separatorInset = separatorInset
|
||||
|
||||
skillsTableView.registerNib(UINib(nibName: editSkillCellID, bundle: nil), forCellReuseIdentifier: editSkillCellID)
|
||||
@@ -131,10 +131,12 @@ class EditSkillsViewController: BaseViewController {
|
||||
|
||||
for skill in skillsToDelete {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return success
|
||||
}
|
||||
|
||||
if let userSkill = userSkillWithSkillID(skill.id, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(userSkill)
|
||||
}
|
||||
}
|
||||
@@ -170,10 +172,12 @@ class EditSkillsViewController: BaseViewController {
|
||||
|
||||
for skill in skillsToDelete {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return success
|
||||
}
|
||||
|
||||
if let userSkill = userSkillWithSkillID(skill.id, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(userSkill)
|
||||
}
|
||||
}
|
||||
@@ -216,7 +220,7 @@ class EditSkillsViewController: BaseViewController {
|
||||
|
||||
// prepare realm & me
|
||||
|
||||
realm = Realm()
|
||||
realm = try! Realm()
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
@@ -289,7 +293,7 @@ extension EditSkillsViewController: UITableViewDataSource, UITableViewDelegate {
|
||||
|
||||
// delete from local
|
||||
|
||||
self?.realm.write {
|
||||
let _ = try? self?.realm.write {
|
||||
self?.realm.delete(userSkill)
|
||||
|
||||
// 防止连续点击时 Realm 出错
|
||||
|
||||
@@ -84,7 +84,7 @@ class FeedbackViewController: UIViewController {
|
||||
let feedback = Feedback(content: feedbackTextView.text, deviceInfo: deviceInfo)
|
||||
|
||||
sendFeedback(feedback, failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepAlert.alertSorry(message: NSLocalizedString("Network error!", comment: ""), inViewController: self)
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ class FriendsInContactsViewController: BaseViewController {
|
||||
}
|
||||
|
||||
friendsInContacts(uploadContacts, failureHandler: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.activityIndicator.stopAnimating()
|
||||
|
||||
@@ -45,8 +45,8 @@ class LoginByMobileViewController: BaseViewController {
|
||||
mobileNumberTextField.delegate = self
|
||||
mobileNumberTextField.addTarget(self, action: "textFieldDidChange:", forControlEvents: .EditingChanged)
|
||||
|
||||
pickMobileNumberPromptLabelTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 50, 60, 60))
|
||||
mobileNumberTextFieldTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 40, 50, 50))
|
||||
pickMobileNumberPromptLabelTopConstraint.constant = Ruler.iPhoneVertical(30, 50, 60, 60).value
|
||||
mobileNumberTextFieldTopConstraint.constant = Ruler.iPhoneVertical(30, 40, 50, 50).value
|
||||
}
|
||||
|
||||
override func viewWillAppear(animated: Bool) {
|
||||
@@ -64,7 +64,10 @@ class LoginByMobileViewController: BaseViewController {
|
||||
// MARK: Actions
|
||||
|
||||
func adjustAreaCodeTextFieldWidth() {
|
||||
let text = areaCodeTextField.text
|
||||
guard let text = areaCodeTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
let size = text.sizeWithAttributes(areaCodeTextField.editing ? areaCodeTextField.typingAttributes : areaCodeTextField.defaultTextAttributes)
|
||||
|
||||
let width = 32 + (size.width + 22) + 20
|
||||
@@ -78,7 +81,11 @@ class LoginByMobileViewController: BaseViewController {
|
||||
|
||||
func textFieldDidChange(textField: UITextField) {
|
||||
|
||||
nextButton.enabled = !areaCodeTextField.text.isEmpty && !mobileNumberTextField.text.isEmpty
|
||||
guard let areaCode = areaCodeTextField.text, mobile = mobileNumberTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
nextButton.enabled = !areaCode.isEmpty && !mobile.isEmpty
|
||||
|
||||
if textField == areaCodeTextField {
|
||||
adjustAreaCodeTextFieldWidth()
|
||||
@@ -93,13 +100,14 @@ class LoginByMobileViewController: BaseViewController {
|
||||
|
||||
view.endEditing(true)
|
||||
|
||||
let mobile = mobileNumberTextField.text
|
||||
let areaCode = areaCodeTextField.text
|
||||
guard let areaCode = areaCodeTextField.text, mobile = mobileNumberTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
YepHUD.showActivityIndicator()
|
||||
|
||||
sendVerifyCodeOfMobile(mobile, withAreaCode: areaCode, useMethod: .SMS, failureHandler: { [weak self] reason, errorMessage in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepHUD.hideActivityIndicator()
|
||||
|
||||
@@ -129,8 +137,9 @@ class LoginByMobileViewController: BaseViewController {
|
||||
}
|
||||
|
||||
func showLoginVerifyMobile() {
|
||||
let mobile = mobileNumberTextField.text
|
||||
let areaCode = areaCodeTextField.text
|
||||
guard let areaCode = areaCodeTextField.text, mobile = mobileNumberTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
self.performSegueWithIdentifier("showLoginVerifyMobile", sender: ["mobile" : mobile, "areaCode": areaCode])
|
||||
}
|
||||
@@ -172,7 +181,12 @@ extension LoginByMobileViewController: UITextFieldDelegate {
|
||||
}
|
||||
|
||||
func textFieldShouldReturn(textField: UITextField) -> Bool {
|
||||
if !areaCodeTextField.text.isEmpty && !mobileNumberTextField.text.isEmpty {
|
||||
|
||||
guard let areaCode = areaCodeTextField.text, mobile = mobileNumberTextField.text else {
|
||||
return true
|
||||
}
|
||||
|
||||
if !areaCode.isEmpty && !mobile.isEmpty {
|
||||
tryShowLoginVerifyMobile()
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ class LoginVerifyMobileViewController: UIViewController {
|
||||
callMePromptLabel.text = NSLocalizedString("Didn't get it?", comment: "")
|
||||
callMeButton.setTitle(NSLocalizedString("Call me", comment: ""), forState: .Normal)
|
||||
|
||||
verifyMobileNumberPromptLabelTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 50, 60, 60))
|
||||
verifyCodeTextFieldTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 40, 50, 50))
|
||||
callMeButtonTopConstraint.constant = Ruler.match(.iPhoneHeights(10, 20, 40, 40))
|
||||
verifyMobileNumberPromptLabelTopConstraint.constant = Ruler.iPhoneVertical(30, 50, 60, 60).value
|
||||
verifyCodeTextFieldTopConstraint.constant = Ruler.iPhoneVertical(30, 40, 50, 50).value
|
||||
callMeButtonTopConstraint.constant = Ruler.iPhoneVertical(10, 20, 40, 40).value
|
||||
}
|
||||
|
||||
override func viewWillAppear(animated: Bool) {
|
||||
@@ -155,7 +155,11 @@ class LoginVerifyMobileViewController: UIViewController {
|
||||
}
|
||||
|
||||
func textFieldDidChange(textField: UITextField) {
|
||||
haveAppropriateInput = (textField.text.characters.count == YepConfig.verifyCodeLength())
|
||||
guard let text = textField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
haveAppropriateInput = (text.characters.count == YepConfig.verifyCodeLength())
|
||||
}
|
||||
|
||||
func next(sender: UIBarButtonItem) {
|
||||
@@ -166,12 +170,14 @@ class LoginVerifyMobileViewController: UIViewController {
|
||||
|
||||
view.endEditing(true)
|
||||
|
||||
let verifyCode = verifyCodeTextField.text
|
||||
guard let verifyCode = verifyCodeTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
YepHUD.showActivityIndicator()
|
||||
|
||||
loginByMobile(mobile, withAreaCode: areaCode, verifyCode: verifyCode, failureHandler: { [weak self] (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepHUD.hideActivityIndicator()
|
||||
|
||||
|
||||
@@ -104,11 +104,11 @@ class MessageMediaViewController: UIViewController {
|
||||
}
|
||||
|
||||
if
|
||||
let videoFileURL = NSFileManager.yepMessageVideoURLWithName(message.localAttachmentName),
|
||||
let asset = AVURLAsset(URL: videoFileURL, options: [:]),
|
||||
let playerItem = AVPlayerItem(asset: asset) {
|
||||
let videoFileURL = NSFileManager.yepMessageVideoURLWithName(message.localAttachmentName) {
|
||||
let asset = AVURLAsset(URL: videoFileURL, options: [:])
|
||||
let playerItem = AVPlayerItem(asset: asset)
|
||||
|
||||
let x = NSFileManager.defaultManager().fileExistsAtPath(videoFileURL.path!)
|
||||
//let x = NSFileManager.defaultManager().fileExistsAtPath(videoFileURL.path!)
|
||||
|
||||
playerItem.seekToTime(kCMTimeZero)
|
||||
//mediaView.videoPlayerLayer.player.replaceCurrentItemWithPlayerItem(playerItem)
|
||||
@@ -118,8 +118,12 @@ class MessageMediaViewController: UIViewController {
|
||||
|
||||
player.addPeriodicTimeObserverForInterval(CMTimeMakeWithSeconds(0.1, Int32(NSEC_PER_SEC)), queue: nil, usingBlock: { time in
|
||||
|
||||
if player.currentItem.status == .ReadyToPlay {
|
||||
let durationSeconds = CMTimeGetSeconds(player.currentItem.duration)
|
||||
guard let currentItem = player.currentItem else {
|
||||
return
|
||||
}
|
||||
|
||||
if currentItem.status == .ReadyToPlay {
|
||||
let durationSeconds = CMTimeGetSeconds(currentItem.duration)
|
||||
let currentSeconds = CMTimeGetSeconds(time)
|
||||
let coundDownTime = Double(Int((durationSeconds - currentSeconds) * 10)) / 10
|
||||
self.mediaControlView.timeLabel.text = "\(coundDownTime)"
|
||||
@@ -142,7 +146,7 @@ class MessageMediaViewController: UIViewController {
|
||||
|
||||
mediaView.videoPlayerLayer.player = player
|
||||
|
||||
mediaView.videoPlayerLayer.player.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
|
||||
mediaView.videoPlayerLayer.player?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
|
||||
|
||||
//mediaView.videoPlayerLayer.player.play()
|
||||
//mediaView.imageView.removeFromSuperview()
|
||||
@@ -185,7 +189,7 @@ class MessageMediaViewController: UIViewController {
|
||||
override func viewWillDisappear(animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
mediaView.videoPlayerLayer.player.pause()
|
||||
mediaView.videoPlayerLayer.player?.pause()
|
||||
}
|
||||
|
||||
// MARK: Actions
|
||||
@@ -193,7 +197,7 @@ class MessageMediaViewController: UIViewController {
|
||||
func dismiss() {
|
||||
if let message = message {
|
||||
if message.mediaType == MessageMediaType.Video.rawValue {
|
||||
mediaView.videoPlayerLayer.player.removeObserver(self, forKeyPath: "status")
|
||||
mediaView.videoPlayerLayer.player?.removeObserver(self, forKeyPath: "status")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +230,7 @@ class MessageMediaViewController: UIViewController {
|
||||
case AVPlayerStatus.ReadyToPlay:
|
||||
println("ReadyToPlay")
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
self.mediaView.videoPlayerLayer.player.play()
|
||||
self.mediaView.videoPlayerLayer.player?.play()
|
||||
}
|
||||
|
||||
case AVPlayerStatus.Unknown:
|
||||
|
||||
@@ -14,7 +14,7 @@ class YepNavigationController: UINavigationController, UIGestureRecognizerDelega
|
||||
super.viewDidLoad()
|
||||
|
||||
if respondsToSelector("interactivePopGestureRecognizer") {
|
||||
interactivePopGestureRecognizer.delegate = self
|
||||
interactivePopGestureRecognizer?.delegate = self
|
||||
|
||||
delegate = self
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class YepNavigationController: UINavigationController, UIGestureRecognizerDelega
|
||||
|
||||
override func pushViewController(viewController: UIViewController, animated: Bool) {
|
||||
if respondsToSelector("interactivePopGestureRecognizer") && animated {
|
||||
interactivePopGestureRecognizer.enabled = false
|
||||
interactivePopGestureRecognizer?.enabled = false
|
||||
}
|
||||
|
||||
super.pushViewController(viewController, animated: animated)
|
||||
@@ -38,7 +38,7 @@ class YepNavigationController: UINavigationController, UIGestureRecognizerDelega
|
||||
|
||||
override func popToRootViewControllerAnimated(animated: Bool) -> [UIViewController]? {
|
||||
if respondsToSelector("interactivePopGestureRecognizer") && animated {
|
||||
interactivePopGestureRecognizer.enabled = false
|
||||
interactivePopGestureRecognizer?.enabled = false
|
||||
}
|
||||
|
||||
return super.popToRootViewControllerAnimated(animated)
|
||||
@@ -46,7 +46,7 @@ class YepNavigationController: UINavigationController, UIGestureRecognizerDelega
|
||||
|
||||
override func popToViewController(viewController: UIViewController, animated: Bool) -> [UIViewController]? {
|
||||
if respondsToSelector("interactivePopGestureRecognizer") && animated {
|
||||
interactivePopGestureRecognizer.enabled = false
|
||||
interactivePopGestureRecognizer?.enabled = false
|
||||
}
|
||||
|
||||
return super.popToViewController(viewController, animated: false)
|
||||
@@ -54,7 +54,7 @@ class YepNavigationController: UINavigationController, UIGestureRecognizerDelega
|
||||
|
||||
func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
|
||||
if respondsToSelector("interactivePopGestureRecognizer") {
|
||||
interactivePopGestureRecognizer.enabled = true
|
||||
interactivePopGestureRecognizer?.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ class NotificationsViewController: UIViewController {
|
||||
|
||||
tableView.separatorInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 0)
|
||||
|
||||
let realm = Realm()
|
||||
let realm = try! Realm()
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
@@ -129,7 +129,9 @@ class NotificationsViewController: UIViewController {
|
||||
|
||||
func enableDoNotDisturb(failed failed: () -> Void) {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
@@ -140,7 +142,7 @@ class NotificationsViewController: UIViewController {
|
||||
if userDoNotDisturb == nil {
|
||||
let _userDoNotDisturb = UserDoNotDisturb()
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.doNotDisturb = _userDoNotDisturb
|
||||
}
|
||||
|
||||
@@ -165,13 +167,15 @@ class NotificationsViewController: UIViewController {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.doNotDisturb?.isOn = true
|
||||
}
|
||||
}
|
||||
@@ -183,13 +187,15 @@ class NotificationsViewController: UIViewController {
|
||||
|
||||
func disableDoNotDisturb(failed failed: () -> Void) {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
|
||||
if let userDoNotDisturb = me.doNotDisturb {
|
||||
if let _ = me.doNotDisturb {
|
||||
|
||||
let info: JSONDictionary = [
|
||||
"mute_started_at_string": "",
|
||||
@@ -210,14 +216,16 @@ class NotificationsViewController: UIViewController {
|
||||
// clean UI
|
||||
self?.doNotDisturbPeriod = DoNotDisturbPeriod()
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
|
||||
if let userDoNotDisturb = me.doNotDisturb {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
realm.delete(userDoNotDisturb)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,17 +135,17 @@ extension OAuthViewController: NSURLConnectionDelegate {
|
||||
|
||||
let authURL = socialAccount.authURL
|
||||
|
||||
if challenge.protectionSpace.host == authURL.host {
|
||||
if challenge.protectionSpace.host == authURL.host, let trust = challenge.protectionSpace.serverTrust {
|
||||
|
||||
println("OAuthViewController trusting connection to host \(challenge.protectionSpace.host)")
|
||||
|
||||
let credential = NSURLCredential(trust: challenge.protectionSpace.serverTrust)
|
||||
let credential = NSURLCredential(trust: trust)
|
||||
|
||||
challenge.sender.useCredential(credential, forAuthenticationChallenge: challenge)
|
||||
challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)
|
||||
}
|
||||
}
|
||||
|
||||
challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge)
|
||||
challenge.sender?.continueWithoutCredentialForAuthenticationChallenge(challenge)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ class PickLocationViewController: UIViewController {
|
||||
|
||||
var isPicked: Bool {
|
||||
switch self {
|
||||
case .Picked(let _):
|
||||
case .Picked:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -141,7 +141,10 @@ class PickLocationViewController: UIViewController {
|
||||
if let location = self.location {
|
||||
sendLocationAction(locationInfo: location.info)
|
||||
} else {
|
||||
sendLocationAction(locationInfo: Location.Info(coordinate: self.mapView.userLocation.location.coordinate, name: nil))
|
||||
guard let location = self.mapView.userLocation.location else {
|
||||
return
|
||||
}
|
||||
sendLocationAction(locationInfo: Location.Info(coordinate: location.coordinate, name: nil))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -149,7 +152,9 @@ class PickLocationViewController: UIViewController {
|
||||
|
||||
private func updateLocationPinWithCoordinate(coordinate: CLLocationCoordinate2D) {
|
||||
|
||||
mapView.removeAnnotation(locationPin)
|
||||
if let locationPin = locationPin {
|
||||
mapView.removeAnnotation(locationPin)
|
||||
}
|
||||
|
||||
let pin = LocationPin(title: "Pin", subtitle: "User Picked Location", coordinate: coordinate)
|
||||
mapView.addAnnotation(pin)
|
||||
@@ -168,15 +173,18 @@ class PickLocationViewController: UIViewController {
|
||||
}
|
||||
|
||||
func placemarksAroundLocation(location: CLLocation, completion: [CLPlacemark] -> Void) {
|
||||
|
||||
geocoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) in
|
||||
|
||||
if (error != nil) {
|
||||
println("reverse geodcode fail: \(error.localizedDescription)")
|
||||
println("reverse geodcode fail: \(error?.localizedDescription)")
|
||||
|
||||
completion([])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if let placemarks = placemarks as? [CLPlacemark] {
|
||||
if let placemarks = placemarks {
|
||||
|
||||
completion(placemarks)
|
||||
|
||||
@@ -199,12 +207,15 @@ extension PickLocationViewController: MKMapViewDelegate {
|
||||
|
||||
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
|
||||
|
||||
guard let location = userLocation.location else {
|
||||
return
|
||||
}
|
||||
|
||||
if isFirstShowUserLocation {
|
||||
isFirstShowUserLocation = false
|
||||
|
||||
sendButton.enabled = true
|
||||
|
||||
let location = userLocation.location
|
||||
let region = MKCoordinateRegionMakeWithDistance(location.coordinate, 2000, 2000)
|
||||
mapView.setRegion(region, animated: true)
|
||||
|
||||
@@ -213,12 +224,12 @@ extension PickLocationViewController: MKMapViewDelegate {
|
||||
})
|
||||
}
|
||||
|
||||
placemarksAroundLocation(userLocation.location) { placemarks in
|
||||
placemarksAroundLocation(location) { placemarks in
|
||||
self.placemarks = placemarks.filter({ $0.name != nil })
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView! {
|
||||
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
|
||||
|
||||
if let annotation = annotation as? LocationPin {
|
||||
|
||||
@@ -279,7 +290,10 @@ extension PickLocationViewController: UISearchBarDelegate {
|
||||
}
|
||||
|
||||
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
|
||||
let name = searchBar.text
|
||||
|
||||
guard let name = searchBar.text else {
|
||||
return
|
||||
}
|
||||
|
||||
searchPlacesByName(name)
|
||||
|
||||
@@ -291,13 +305,15 @@ extension PickLocationViewController: UISearchBarDelegate {
|
||||
let request = MKLocalSearchRequest()
|
||||
request.naturalLanguageQuery = name
|
||||
|
||||
request.region = MKCoordinateRegionMakeWithDistance(mapView.userLocation.location.coordinate, 200000, 200000)
|
||||
if let location = mapView.userLocation.location {
|
||||
request.region = MKCoordinateRegionMakeWithDistance(location.coordinate, 200000, 200000)
|
||||
}
|
||||
|
||||
let search = MKLocalSearch(request: request)
|
||||
|
||||
search.startWithCompletionHandler { [weak self] response, error in
|
||||
if error == nil {
|
||||
if let mapItems = response.mapItems as? [MKMapItem] {
|
||||
if let mapItems = response?.mapItems {
|
||||
|
||||
let searchedMapItems = mapItems.filter({ $0.placemark.name != nil })
|
||||
|
||||
@@ -381,11 +397,8 @@ extension PickLocationViewController: UITableViewDataSource, UITableViewDelegate
|
||||
cell.iconImageView.hidden = false
|
||||
cell.iconImageView.image = UIImage(named: "icon_pin")
|
||||
|
||||
if let placemark = searchedMapItems[indexPath.row].placemark {
|
||||
cell.locationLabel.text = placemark.name ?? ""
|
||||
} else {
|
||||
cell.locationLabel.text = ""
|
||||
}
|
||||
let placemark = searchedMapItems[indexPath.row].placemark
|
||||
cell.locationLabel.text = placemark.name
|
||||
|
||||
cell.checkImageView.hidden = true
|
||||
|
||||
@@ -445,11 +458,17 @@ extension PickLocationViewController: UITableViewDataSource, UITableViewDelegate
|
||||
|
||||
case Section.Placemarks.rawValue:
|
||||
let placemark = placemarks[indexPath.row]
|
||||
location = .Selected(info: Location.Info(coordinate: placemark.location.coordinate, name: placemark.name))
|
||||
guard let _location = placemark.location else {
|
||||
break
|
||||
}
|
||||
location = .Selected(info: Location.Info(coordinate: _location.coordinate, name: placemark.name))
|
||||
|
||||
case Section.SearchedLocation.rawValue:
|
||||
let placemark = self.searchedMapItems[indexPath.row].placemark
|
||||
location = .Selected(info: Location.Info(coordinate: placemark.location.coordinate, name: placemark.name))
|
||||
guard let _location = placemark.location else {
|
||||
break
|
||||
}
|
||||
location = .Selected(info: Location.Info(coordinate: _location.coordinate, name: placemark.name))
|
||||
|
||||
case Section.FoursquareVenue.rawValue:
|
||||
let foursquareVenue = foursquareVenues[indexPath.row]
|
||||
|
||||
@@ -18,7 +18,7 @@ class ProfileLayout: UICollectionViewFlowLayout {
|
||||
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||
|
||||
let layoutAttributes = super.layoutAttributesForElementsInRect(rect) as! [UICollectionViewLayoutAttributes]
|
||||
let layoutAttributes = super.layoutAttributesForElementsInRect(rect)
|
||||
let contentInset = collectionView!.contentInset
|
||||
let contentOffset = collectionView!.contentOffset
|
||||
|
||||
@@ -27,14 +27,16 @@ class ProfileLayout: UICollectionViewFlowLayout {
|
||||
if contentOffset.y < minY {
|
||||
let deltaY = abs(contentOffset.y - minY)
|
||||
|
||||
for attributes in layoutAttributes {
|
||||
if attributes.indexPath.section == ProfileViewController.ProfileSection.Header.rawValue {
|
||||
var frame = attributes.frame
|
||||
frame.size.height = max(minY, CGRectGetWidth(collectionView!.bounds) * profileAvatarAspectRatio + deltaY)
|
||||
frame.origin.y = CGRectGetMinY(frame) - deltaY
|
||||
attributes.frame = frame
|
||||
if let layoutAttributes = layoutAttributes {
|
||||
for attributes in layoutAttributes {
|
||||
if attributes.indexPath.section == ProfileViewController.ProfileSection.Header.rawValue {
|
||||
var frame = attributes.frame
|
||||
frame.size.height = max(minY, CGRectGetWidth(collectionView!.bounds) * profileAvatarAspectRatio + deltaY)
|
||||
frame.origin.y = CGRectGetMinY(frame) - deltaY
|
||||
attributes.frame = frame
|
||||
|
||||
break
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +48,16 @@ class ProfileLayout: UICollectionViewFlowLayout {
|
||||
|
||||
let deltaY = abs(contentOffset.y - minY)
|
||||
|
||||
for attributes in layoutAttributes {
|
||||
if attributes.indexPath.section == ProfileViewController.ProfileSection.Header.rawValue {
|
||||
var frame = attributes.frame
|
||||
frame.origin.y = deltaY - coverHideHeight
|
||||
attributes.frame = frame
|
||||
attributes.zIndex = 1000
|
||||
if let layoutAttributes = layoutAttributes {
|
||||
for attributes in layoutAttributes {
|
||||
if attributes.indexPath.section == ProfileViewController.ProfileSection.Header.rawValue {
|
||||
var frame = attributes.frame
|
||||
frame.origin.y = deltaY - coverHideHeight
|
||||
attributes.frame = frame
|
||||
attributes.zIndex = 1000
|
||||
|
||||
break
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,16 +73,19 @@ class ProfileLayout: UICollectionViewFlowLayout {
|
||||
|
||||
// 先按照每个 item 的 centerY 分组
|
||||
var rowCollections = [CGFloat: [UICollectionViewLayoutAttributes]]()
|
||||
for attributes in layoutAttributes {
|
||||
let centerY = CGRectGetMidY(attributes.frame)
|
||||
|
||||
if let rowCollection = rowCollections[centerY] {
|
||||
var rowCollection = rowCollection
|
||||
rowCollection.append(attributes)
|
||||
rowCollections[centerY] = rowCollection
|
||||
if let layoutAttributes = layoutAttributes {
|
||||
for attributes in layoutAttributes {
|
||||
let centerY = CGRectGetMidY(attributes.frame)
|
||||
|
||||
} else {
|
||||
rowCollections[centerY] = [attributes]
|
||||
if let rowCollection = rowCollections[centerY] {
|
||||
var rowCollection = rowCollection
|
||||
rowCollection.append(attributes)
|
||||
rowCollections[centerY] = rowCollection
|
||||
|
||||
} else {
|
||||
rowCollections[centerY] = [attributes]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -404,30 +404,34 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
var masterSkills = [Skill]() {
|
||||
didSet {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.masterSkills.removeAll()
|
||||
let userSkills = userSkillsFromSkills(self.masterSkills, inRealm: realm)
|
||||
me.masterSkills.extend(userSkills)
|
||||
me.masterSkills.appendContentsOf(userSkills)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var learningSkills = [Skill]() {
|
||||
didSet {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.learningSkills.removeAll()
|
||||
let userSkills = userSkillsFromSkills(self.learningSkills, inRealm: realm)
|
||||
me.learningSkills.extend(userSkills)
|
||||
me.learningSkills.appendContentsOf(userSkills)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -494,7 +498,11 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
case .DiscoveredUserType(let discoveredUser):
|
||||
|
||||
if let user = userWithUserID(discoveredUser.id, inRealm: Realm()) {
|
||||
guard let realm = try? Realm() else {
|
||||
break
|
||||
}
|
||||
|
||||
if let user = userWithUserID(discoveredUser.id, inRealm: realm) {
|
||||
self.profileUser = ProfileUser.UserType(user)
|
||||
|
||||
masterSkills = skillsFromUserSkillList(user.masterSkills)
|
||||
@@ -511,7 +519,8 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: Realm()) {
|
||||
realm = try? Realm(),
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
profileUser = ProfileUser.UserType(me)
|
||||
|
||||
masterSkills = skillsFromUserSkillList(me.masterSkills)
|
||||
@@ -642,7 +651,8 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: Realm()) {
|
||||
realm = try? Realm(),
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
|
||||
if me.masterSkills.count == 0 && me.learningSkills.count == 0 {
|
||||
|
||||
@@ -707,7 +717,8 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
if let
|
||||
avatarURLString = profileUser?.avatarURLString,
|
||||
avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm()) {
|
||||
realm = try? Realm(),
|
||||
avatar = avatarWithAvatarURLString(avatarURLString, inRealm: realm) {
|
||||
if let
|
||||
avatarFileURL = NSFileManager.yepAvatarURLWithName(avatar.avatarFileName),
|
||||
avatarFilePath = avatarFileURL.path,
|
||||
@@ -773,11 +784,13 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
}, completion: { success in
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.username = newUsername
|
||||
}
|
||||
}
|
||||
@@ -846,7 +859,9 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
if let profileUser = profileUser {
|
||||
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
switch profileUser {
|
||||
|
||||
@@ -860,57 +875,55 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
newUser.friendState = UserFriendState.Stranger.rawValue
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newUser)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newUser)
|
||||
}
|
||||
|
||||
stranger = newUser
|
||||
}
|
||||
|
||||
if let user = stranger {
|
||||
|
||||
realm.beginWrite()
|
||||
let _ = try? realm.write {
|
||||
|
||||
// 更新用户信息
|
||||
// 更新用户信息
|
||||
|
||||
user.lastSignInUnixTime = discoveredUser.lastSignInUnixTime
|
||||
user.lastSignInUnixTime = discoveredUser.lastSignInUnixTime
|
||||
|
||||
user.username = discoveredUser.username ?? ""
|
||||
user.username = discoveredUser.username ?? ""
|
||||
|
||||
user.nickname = discoveredUser.nickname
|
||||
user.nickname = discoveredUser.nickname
|
||||
|
||||
if let introduction = discoveredUser.introduction {
|
||||
user.introduction = introduction
|
||||
if let introduction = discoveredUser.introduction {
|
||||
user.introduction = introduction
|
||||
}
|
||||
|
||||
user.avatarURLString = discoveredUser.avatarURLString
|
||||
|
||||
user.longitude = discoveredUser.longitude
|
||||
|
||||
user.latitude = discoveredUser.latitude
|
||||
|
||||
if let badge = discoveredUser.badge {
|
||||
user.badge = badge
|
||||
}
|
||||
|
||||
// 更新技能
|
||||
|
||||
user.learningSkills.removeAll()
|
||||
let learningUserSkills = userSkillsFromSkills(discoveredUser.learningSkills, inRealm: realm)
|
||||
user.learningSkills.appendContentsOf(learningUserSkills)
|
||||
|
||||
user.masterSkills.removeAll()
|
||||
let masterUserSkills = userSkillsFromSkills(discoveredUser.masterSkills, inRealm: realm)
|
||||
user.masterSkills.appendContentsOf(masterUserSkills)
|
||||
|
||||
// 更新 Social Account Provider
|
||||
|
||||
user.socialAccountProviders.removeAll()
|
||||
let socialAccountProviders = userSocialAccountProvidersFromSocialAccountProviders(discoveredUser.socialAccountProviders)
|
||||
user.socialAccountProviders.appendContentsOf(socialAccountProviders)
|
||||
}
|
||||
|
||||
user.avatarURLString = discoveredUser.avatarURLString
|
||||
|
||||
user.longitude = discoveredUser.longitude
|
||||
|
||||
user.latitude = discoveredUser.latitude
|
||||
|
||||
if let badge = discoveredUser.badge {
|
||||
user.badge = badge
|
||||
}
|
||||
|
||||
// 更新技能
|
||||
|
||||
user.learningSkills.removeAll()
|
||||
let learningUserSkills = userSkillsFromSkills(discoveredUser.learningSkills, inRealm: realm)
|
||||
user.learningSkills.extend(learningUserSkills)
|
||||
|
||||
user.masterSkills.removeAll()
|
||||
let masterUserSkills = userSkillsFromSkills(discoveredUser.masterSkills, inRealm: realm)
|
||||
user.masterSkills.extend(masterUserSkills)
|
||||
|
||||
// 更新 Social Account Provider
|
||||
|
||||
user.socialAccountProviders.removeAll()
|
||||
let socialAccountProviders = userSocialAccountProvidersFromSocialAccountProviders(discoveredUser.socialAccountProviders)
|
||||
user.socialAccountProviders.extend(socialAccountProviders)
|
||||
|
||||
realm.commitWrite()
|
||||
|
||||
|
||||
if user.conversation == nil {
|
||||
let newConversation = Conversation()
|
||||
@@ -918,9 +931,9 @@ class ProfileViewController: UIViewController {
|
||||
newConversation.type = ConversationType.OneToOne.rawValue
|
||||
newConversation.withFriend = user
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newConversation)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newConversation)
|
||||
}
|
||||
}
|
||||
|
||||
if let conversation = user.conversation {
|
||||
@@ -940,9 +953,9 @@ class ProfileViewController: UIViewController {
|
||||
newConversation.type = ConversationType.OneToOne.rawValue
|
||||
newConversation.withFriend = user
|
||||
|
||||
realm.beginWrite()
|
||||
realm.add(newConversation)
|
||||
realm.commitWrite()
|
||||
let _ = try? realm.write {
|
||||
realm.add(newConversation)
|
||||
}
|
||||
}
|
||||
|
||||
if let conversation = user.conversation {
|
||||
@@ -1095,7 +1108,9 @@ class ProfileViewController: UIViewController {
|
||||
let providerName = socialAccount.rawValue
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
@@ -1104,7 +1119,7 @@ class ProfileViewController: UIViewController {
|
||||
var haveSocialAccountProvider = false
|
||||
for socialAccountProvider in me.socialAccountProviders {
|
||||
if socialAccountProvider.name == providerName {
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
socialAccountProvider.enabled = true
|
||||
}
|
||||
|
||||
@@ -1119,7 +1134,7 @@ class ProfileViewController: UIViewController {
|
||||
provider.name = providerName
|
||||
provider.enabled = true
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
me.socialAccountProviders.append(provider)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,9 +88,7 @@ class RegisterPickAvatarViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
lazy var sessionQueue = {
|
||||
return dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL)
|
||||
}()
|
||||
lazy var sessionQueue: dispatch_queue_t = dispatch_queue_create("session_queue", DISPATCH_QUEUE_SERIAL)
|
||||
|
||||
lazy var session: AVCaptureSession = {
|
||||
let _session = AVCaptureSession()
|
||||
@@ -101,14 +99,12 @@ class RegisterPickAvatarViewController: UIViewController {
|
||||
|
||||
let mediaType = AVMediaTypeVideo
|
||||
|
||||
lazy var videoDeviceInput: AVCaptureDeviceInput = {
|
||||
var error: NSError? = nil
|
||||
let videoDevice = self.deviceWithMediaType(self.mediaType, preferringPosition: .Front)
|
||||
do {
|
||||
return try AVCaptureDeviceInput(device: videoDevice!)
|
||||
} catch _ {
|
||||
lazy var videoDeviceInput: AVCaptureDeviceInput? = {
|
||||
guard let videoDevice = self.deviceWithMediaType(self.mediaType, preferringPosition: .Front) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return try? AVCaptureDeviceInput(device: videoDevice)
|
||||
}()
|
||||
|
||||
lazy var stillImageOutput: AVCaptureStillImageOutput = {
|
||||
@@ -271,7 +267,9 @@ class RegisterPickAvatarViewController: UIViewController {
|
||||
let data = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
|
||||
var image = UIImage(data: data)!
|
||||
|
||||
image = UIImage(CGImage: image.CGImage, scale: image.scale, orientation: .LeftMirrored)!
|
||||
if let CGImage = image.CGImage {
|
||||
image = UIImage(CGImage: CGImage, scale: image.scale, orientation: .LeftMirrored)
|
||||
}
|
||||
|
||||
image = image.fixRotation().largestCenteredSquareImage()
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ class RegisterPickMobileViewController: UIViewController {
|
||||
mobileNumberTextField.delegate = self
|
||||
mobileNumberTextField.addTarget(self, action: "textFieldDidChange:", forControlEvents: .EditingChanged)
|
||||
|
||||
pickMobileNumberPromptLabelTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 50, 60, 60))
|
||||
mobileNumberTextFieldTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 40, 50, 50))
|
||||
pickMobileNumberPromptLabelTopConstraint.constant = Ruler.iPhoneVertical(30, 50, 60, 60).value
|
||||
mobileNumberTextFieldTopConstraint.constant = Ruler.iPhoneVertical(30, 40, 50, 50).value
|
||||
}
|
||||
|
||||
override func viewWillAppear(animated: Bool) {
|
||||
@@ -62,7 +62,11 @@ class RegisterPickMobileViewController: UIViewController {
|
||||
// MARK: Actions
|
||||
|
||||
func adjustAreaCodeTextFieldWidth() {
|
||||
let text = areaCodeTextField.text
|
||||
|
||||
guard let text = areaCodeTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
let size = text.sizeWithAttributes(areaCodeTextField.editing ? areaCodeTextField.typingAttributes : areaCodeTextField.defaultTextAttributes)
|
||||
|
||||
let width = 32 + (size.width + 22) + 20
|
||||
@@ -75,8 +79,12 @@ class RegisterPickMobileViewController: UIViewController {
|
||||
}
|
||||
|
||||
func textFieldDidChange(textField: UITextField) {
|
||||
|
||||
guard let areaCode = areaCodeTextField.text, mobileNumber = mobileNumberTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
nextButton.enabled = !areaCodeTextField.text.isEmpty && !mobileNumberTextField.text.isEmpty
|
||||
nextButton.enabled = !areaCode.isEmpty && !mobileNumber.isEmpty
|
||||
|
||||
if textField == areaCodeTextField {
|
||||
adjustAreaCodeTextFieldWidth()
|
||||
@@ -91,13 +99,14 @@ class RegisterPickMobileViewController: UIViewController {
|
||||
|
||||
view.endEditing(true)
|
||||
|
||||
let mobile = mobileNumberTextField.text
|
||||
let areaCode = areaCodeTextField.text
|
||||
guard let mobile = mobileNumberTextField.text, areaCode = areaCodeTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
YepHUD.showActivityIndicator()
|
||||
|
||||
validateMobile(mobile, withAreaCode: areaCode, failureHandler: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepHUD.hideActivityIndicator()
|
||||
|
||||
@@ -106,7 +115,7 @@ class RegisterPickMobileViewController: UIViewController {
|
||||
println("ValidateMobile: available")
|
||||
|
||||
registerMobile(mobile, withAreaCode: areaCode, nickname: nickname, failureHandler: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepHUD.hideActivityIndicator()
|
||||
|
||||
@@ -191,7 +200,12 @@ extension RegisterPickMobileViewController: UITextFieldDelegate {
|
||||
}
|
||||
|
||||
func textFieldShouldReturn(textField: UITextField) -> Bool {
|
||||
if !areaCodeTextField.text.isEmpty && !mobileNumberTextField.text.isEmpty {
|
||||
|
||||
guard let mobile = mobileNumberTextField.text, areaCode = areaCodeTextField.text else {
|
||||
return false
|
||||
}
|
||||
|
||||
if !areaCode.isEmpty && !mobile.isEmpty {
|
||||
tryShowRegisterVerifyMobile()
|
||||
}
|
||||
|
||||
|
||||
@@ -43,12 +43,12 @@ class RegisterPickNameViewController: BaseViewController {
|
||||
pickNamePromptLabel.text = NSLocalizedString("What's your name?", comment: "")
|
||||
|
||||
let text = NSLocalizedString("By tap Next you agree to our terms.", comment: "")
|
||||
let textAttributes: [NSObject: AnyObject] = [
|
||||
let textAttributes: [String: AnyObject] = [
|
||||
NSFontAttributeName: UIFont.systemFontOfSize(14),
|
||||
NSForegroundColorAttributeName: UIColor.grayColor(),
|
||||
]
|
||||
var attributedText = NSMutableAttributedString(string: text, attributes: textAttributes)
|
||||
let termsAttributes: [NSObject: AnyObject] = [
|
||||
let attributedText = NSMutableAttributedString(string: text, attributes: textAttributes)
|
||||
let termsAttributes: [String: AnyObject] = [
|
||||
NSForegroundColorAttributeName: UIColor.yepTintColor(),
|
||||
NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue,
|
||||
]
|
||||
@@ -67,8 +67,8 @@ class RegisterPickNameViewController: BaseViewController {
|
||||
nameTextField.delegate = self
|
||||
nameTextField.addTarget(self, action: "textFieldDidChange:", forControlEvents: .EditingChanged)
|
||||
|
||||
pickNamePromptLabelTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 50, 60, 60))
|
||||
nameTextFieldTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 40, 50, 50))
|
||||
pickNamePromptLabelTopConstraint.constant = Ruler.iPhoneVertical(30, 50, 60, 60).value
|
||||
nameTextFieldTopConstraint.constant = Ruler.iPhoneVertical(30, 40, 50, 50).value
|
||||
}
|
||||
|
||||
override func viewWillAppear(animated: Bool) {
|
||||
@@ -90,7 +90,11 @@ class RegisterPickNameViewController: BaseViewController {
|
||||
}
|
||||
|
||||
func textFieldDidChange(textField: UITextField) {
|
||||
isDirty = !textField.text.isEmpty
|
||||
guard let text = textField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
isDirty = !text.isEmpty
|
||||
}
|
||||
|
||||
func next(sender: UIBarButtonItem) {
|
||||
@@ -98,7 +102,12 @@ class RegisterPickNameViewController: BaseViewController {
|
||||
}
|
||||
|
||||
private func showRegisterPickMobile() {
|
||||
let nickname = nameTextField.text.trimming(.WhitespaceAndNewline)
|
||||
|
||||
guard let text = nameTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
let nickname = text.trimming(.WhitespaceAndNewline)
|
||||
YepUserDefaults.nickname.value = nickname
|
||||
|
||||
performSegueWithIdentifier("showRegisterPickMobile", sender: nil)
|
||||
@@ -108,7 +117,12 @@ class RegisterPickNameViewController: BaseViewController {
|
||||
extension RegisterPickNameViewController: UITextFieldDelegate {
|
||||
|
||||
func textFieldShouldReturn(textField: UITextField) -> Bool {
|
||||
if !textField.text.isEmpty {
|
||||
|
||||
guard let text = textField.text else {
|
||||
return true
|
||||
}
|
||||
|
||||
if !text.isEmpty {
|
||||
showRegisterPickMobile()
|
||||
}
|
||||
|
||||
|
||||
@@ -13,25 +13,28 @@ let registerPickSkillsLayoutLeftEdgeInset: CGFloat = 20
|
||||
class RegisterPickSkillsLayout: UICollectionViewFlowLayout {
|
||||
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||
let layoutAttributes = super.layoutAttributesForElementsInRect(rect) as! [UICollectionViewLayoutAttributes]
|
||||
let layoutAttributes = super.layoutAttributesForElementsInRect(rect)
|
||||
|
||||
// 先按照每个 item 的 centerY 分组
|
||||
|
||||
var rowCollections = [CGFloat: [UICollectionViewLayoutAttributes]]()
|
||||
for (index, attributes) in layoutAttributes.enumerate() {
|
||||
let centerY = CGRectGetMidY(attributes.frame)
|
||||
if let layoutAttributes = layoutAttributes {
|
||||
for (_, attributes) in layoutAttributes.enumerate() {
|
||||
let centerY = CGRectGetMidY(attributes.frame)
|
||||
|
||||
if let rowCollection = rowCollections[centerY] {
|
||||
var rowCollection = rowCollection
|
||||
rowCollection.append(attributes)
|
||||
rowCollections[centerY] = rowCollection
|
||||
if let rowCollection = rowCollections[centerY] {
|
||||
var rowCollection = rowCollection
|
||||
rowCollection.append(attributes)
|
||||
rowCollections[centerY] = rowCollection
|
||||
|
||||
} else {
|
||||
rowCollections[centerY] = [attributes]
|
||||
} else {
|
||||
rowCollections[centerY] = [attributes]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 再调整每一行的 item 的 frame
|
||||
for (key, rowCollection) in rowCollections {
|
||||
for (_, rowCollection) in rowCollections {
|
||||
let rowItemsCount = rowCollection.count
|
||||
|
||||
// 每一行总的 InteritemSpacing
|
||||
@@ -45,7 +48,7 @@ class RegisterPickSkillsLayout: UICollectionViewFlowLayout {
|
||||
|
||||
// 计算出有效的 width 和需要偏移的 offset
|
||||
let alignmentWidth = aggregateItemsWidth + aggregateInteritemSpacing
|
||||
let alignmentOffsetX = (CGRectGetWidth(collectionView!.bounds) - alignmentWidth) / 2
|
||||
//let alignmentOffsetX = (CGRectGetWidth(collectionView!.bounds) - alignmentWidth) / 2
|
||||
|
||||
// 调整每个 item 的 origin.x 即可
|
||||
var previousFrame = CGRectZero
|
||||
@@ -74,3 +77,4 @@ class RegisterPickSkillsLayout: UICollectionViewFlowLayout {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class RegisterPickSkillsSelectSkillsTransitionManager: NSObject, UIViewControlle
|
||||
|
||||
if isPresentation {
|
||||
if let view = toView {
|
||||
containerView.addSubview(view)
|
||||
containerView?.addSubview(view)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,29 +13,32 @@ class RegisterSelectSkillsLayout: UICollectionViewFlowLayout {
|
||||
let leftEdgeInset: CGFloat = 20
|
||||
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||
let layoutAttributes = super.layoutAttributesForElementsInRect(rect) as! [UICollectionViewLayoutAttributes]
|
||||
let layoutAttributes = super.layoutAttributesForElementsInRect(rect)
|
||||
|
||||
// 先按照每个 item 的 centerY 分组
|
||||
var rowCollections = [CGFloat: [UICollectionViewLayoutAttributes]]()
|
||||
for (index, attributes) in layoutAttributes.enumerate() {
|
||||
let centerY = CGRectGetMidY(attributes.frame)
|
||||
|
||||
if let rowCollection = rowCollections[centerY] {
|
||||
var rowCollection = rowCollection
|
||||
rowCollection.append(attributes)
|
||||
rowCollections[centerY] = rowCollection
|
||||
if let layoutAttributes = layoutAttributes {
|
||||
for (_, attributes) in layoutAttributes.enumerate() {
|
||||
let centerY = CGRectGetMidY(attributes.frame)
|
||||
|
||||
} else {
|
||||
rowCollections[centerY] = [attributes]
|
||||
if let rowCollection = rowCollections[centerY] {
|
||||
var rowCollection = rowCollection
|
||||
rowCollection.append(attributes)
|
||||
rowCollections[centerY] = rowCollection
|
||||
|
||||
} else {
|
||||
rowCollections[centerY] = [attributes]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 再调整每一行的 item 的 frame
|
||||
for (key, rowCollection) in rowCollections {
|
||||
for (_, rowCollection) in rowCollections {
|
||||
let rowItemsCount = rowCollection.count
|
||||
|
||||
// 每一行总的 InteritemSpacing
|
||||
let aggregateInteritemSpacing = minimumInteritemSpacing * CGFloat(rowItemsCount - 1)
|
||||
//let aggregateInteritemSpacing = minimumInteritemSpacing * CGFloat(rowItemsCount - 1)
|
||||
|
||||
// 每一行所有 items 的宽度
|
||||
var aggregateItemsWidth: CGFloat = 0
|
||||
@@ -44,8 +47,8 @@ class RegisterSelectSkillsLayout: UICollectionViewFlowLayout {
|
||||
}
|
||||
|
||||
// 计算出有效的 width 和需要偏移的 offset
|
||||
let alignmentWidth = aggregateItemsWidth + aggregateInteritemSpacing
|
||||
let alignmentOffsetX = (CGRectGetWidth(collectionView!.bounds) - alignmentWidth) / 2
|
||||
//let alignmentWidth = aggregateItemsWidth + aggregateInteritemSpacing
|
||||
//let alignmentOffsetX = (CGRectGetWidth(collectionView!.bounds) - alignmentWidth) / 2
|
||||
|
||||
// 调整每个 item 的 origin.x 即可
|
||||
var previousFrame = CGRectZero
|
||||
@@ -84,3 +87,4 @@ class RegisterSelectSkillsLayout: UICollectionViewFlowLayout {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
|
||||
override func prepareLayout() {
|
||||
super.prepareLayout()
|
||||
var contentOffset = self.collectionView!.contentOffset
|
||||
let contentOffset = self.collectionView!.contentOffset
|
||||
|
||||
// only refresh the set of UIAttachmentBehaviours if we've moved more than the scroll threshold since last load
|
||||
if (fabsf(Float(contentOffset.y) - Float(lastContentOffset.y)) < Float(kScrollRefreshThreshold)) && visibleIndexPaths.count > 0{
|
||||
@@ -46,18 +46,23 @@ class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
}
|
||||
lastContentOffset = contentOffset
|
||||
|
||||
var padding = kScrollPaddingRect
|
||||
var currentRect = CGRectMake(0, contentOffset.y - padding, self.collectionView!.frame.size.width, self.collectionView!.frame.size.height + 3 * padding)
|
||||
let padding = kScrollPaddingRect
|
||||
let currentRect = CGRectMake(0, contentOffset.y - padding, self.collectionView!.frame.size.width, self.collectionView!.frame.size.height + 3 * padding)
|
||||
|
||||
var itemsInCurrentRect = super.layoutAttributesForElementsInRect(currentRect)! as NSArray
|
||||
var indexPathsInVisibleRect = NSSet(array: itemsInCurrentRect.valueForKey("indexPath") as! [AnyObject])
|
||||
let itemsInCurrentRect = super.layoutAttributesForElementsInRect(currentRect)! as NSArray
|
||||
let indexPathsInVisibleRect = NSSet(array: itemsInCurrentRect.valueForKey("indexPath") as! [AnyObject])
|
||||
|
||||
// Remove behaviours that are no longer visible
|
||||
|
||||
for behaviour in animator!.behaviors as! [UIAttachmentBehavior] {
|
||||
var indexPath = behaviour.items.first?.indexPath
|
||||
|
||||
guard let items = behaviour.items as? [UICollectionViewLayoutAttributes] else {
|
||||
continue
|
||||
}
|
||||
|
||||
let indexPath = items.first?.indexPath
|
||||
|
||||
var isInVisibleIndexPaths = indexPathsInVisibleRect.member(indexPath!) != nil
|
||||
let isInVisibleIndexPaths = indexPathsInVisibleRect.member(indexPath!) != nil
|
||||
if (!isInVisibleIndexPaths){
|
||||
animator.removeBehavior(behaviour)
|
||||
visibleIndexPaths.removeObject(indexPath!)
|
||||
@@ -65,13 +70,13 @@ class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
}
|
||||
|
||||
// Find newly visible indexes
|
||||
var newVisibleItems = itemsInCurrentRect.filteredArrayUsingPredicate(NSPredicate(block: { (item, bindings) -> Bool in
|
||||
var isInVisibleIndexPaths = self.visibleIndexPaths.member(item.indexPath) != nil
|
||||
let newVisibleItems = itemsInCurrentRect.filteredArrayUsingPredicate(NSPredicate(block: { (item, bindings) -> Bool in
|
||||
let isInVisibleIndexPaths = self.visibleIndexPaths.member(item.indexPath) != nil
|
||||
return !isInVisibleIndexPaths
|
||||
}));
|
||||
|
||||
for attribute in newVisibleItems as! [UICollectionViewLayoutAttributes] {
|
||||
var spring = UIAttachmentBehavior(item: attribute, attachedToAnchor: attribute.center)
|
||||
let spring = UIAttachmentBehavior(item: attribute, attachedToAnchor: attribute.center)
|
||||
spring.length = 0
|
||||
spring.frequency = 1.5
|
||||
spring.damping = 0.8
|
||||
@@ -96,7 +101,7 @@ class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
attributes.center.y += lastScrollDelta > 0 ? min(scrollDelta, scrollDelta * scrollResistance) : max(scrollDelta, scrollDelta * scrollResistance)
|
||||
}
|
||||
|
||||
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
|
||||
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
if let layoutAttributes = animator!.layoutAttributesForCellAtIndexPath(indexPath) {
|
||||
return layoutAttributes
|
||||
} else {
|
||||
@@ -108,9 +113,9 @@ class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||
var newRect = rect
|
||||
let padding:CGFloat = kScrollPaddingRect
|
||||
newRect.size.height += 3.0*padding
|
||||
newRect.size.height += 3.0 * padding
|
||||
newRect.origin.y -= padding
|
||||
return animator!.itemsInRect(newRect)
|
||||
return animator?.itemsInRect(newRect) as? [UICollectionViewLayoutAttributes]
|
||||
}
|
||||
|
||||
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
|
||||
@@ -121,8 +126,11 @@ class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
lastTouchLocation = scrollView.panGestureRecognizer.locationInView(scrollView)
|
||||
|
||||
for behaviour in animator!.behaviors as! [UIAttachmentBehavior] {
|
||||
self.adjustSpring(behaviour, touchLocation: lastTouchLocation, scrollDelta: lastScrollDelta)
|
||||
animator!.updateItemUsingCurrentState(behaviour.items.first as! UIDynamicItem)
|
||||
adjustSpring(behaviour, touchLocation: lastTouchLocation, scrollDelta: lastScrollDelta)
|
||||
|
||||
if let firstItem = behaviour.items.first {
|
||||
animator?.updateItemUsingCurrentState(firstItem)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
@@ -133,10 +141,11 @@ class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
visibleIndexPaths.removeAllObjects()
|
||||
}
|
||||
|
||||
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
|
||||
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, withIndexPath: indexPath)
|
||||
attributes.frame = CGRect(x: 0, y: 0, width: 320, height: 50)
|
||||
|
||||
return attributes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ class RegisterVerifyMobileViewController: UIViewController {
|
||||
callMePromptLabel.text = NSLocalizedString("Didn't get it?", comment: "")
|
||||
callMeButton.setTitle(NSLocalizedString("Call me", comment: ""), forState: .Normal)
|
||||
|
||||
verifyMobileNumberPromptLabelTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 50, 60, 60))
|
||||
verifyCodeTextFieldTopConstraint.constant = Ruler.match(.iPhoneHeights(30, 40, 50, 50))
|
||||
callMeButtonTopConstraint.constant = Ruler.match(.iPhoneHeights(10, 20, 40, 40))
|
||||
verifyMobileNumberPromptLabelTopConstraint.constant = Ruler.iPhoneVertical(30, 50, 60, 60).value
|
||||
verifyCodeTextFieldTopConstraint.constant = Ruler.iPhoneVertical(30, 40, 50, 50).value
|
||||
callMeButtonTopConstraint.constant = Ruler.iPhoneVertical(10, 20, 40, 40).value
|
||||
}
|
||||
|
||||
override func viewWillAppear(animated: Bool) {
|
||||
@@ -154,7 +154,11 @@ class RegisterVerifyMobileViewController: UIViewController {
|
||||
}
|
||||
|
||||
func textFieldDidChange(textField: UITextField) {
|
||||
haveAppropriateInput = (textField.text.characters.count == YepConfig.verifyCodeLength())
|
||||
guard let text = textField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
haveAppropriateInput = (text.characters.count == YepConfig.verifyCodeLength())
|
||||
}
|
||||
|
||||
func next(sender: UIBarButtonItem) {
|
||||
@@ -165,12 +169,14 @@ class RegisterVerifyMobileViewController: UIViewController {
|
||||
|
||||
view.endEditing(true)
|
||||
|
||||
let verifyCode = verifyCodeTextField.text
|
||||
guard let verifyCode = verifyCodeTextField.text else {
|
||||
return
|
||||
}
|
||||
|
||||
YepHUD.showActivityIndicator()
|
||||
|
||||
verifyMobile(mobile, withAreaCode: areaCode, verifyCode: verifyCode, failureHandler: { [weak self] (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
defaultFailureHandler(reason, errorMessage: errorMessage)
|
||||
|
||||
YepHUD.hideActivityIndicator()
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ class ShowStepViewController: UIViewController {
|
||||
|
||||
titleLabel.textColor = UIColor.yepTintColor()
|
||||
|
||||
titleLabelBottomConstraint.constant = Ruler.match(.iPhoneHeights(20, 30, 30, 30))
|
||||
subTitleLabelBottomConstraint.constant = Ruler.match(.iPhoneHeights(120, 140, 160, 180))
|
||||
titleLabelBottomConstraint.constant = Ruler.iPhoneVertical(20, 30, 30, 30).value
|
||||
subTitleLabelBottomConstraint.constant = Ruler.iPhoneVertical(120, 140, 160, 180).value
|
||||
}
|
||||
|
||||
func repeatAnimate(view: UIView, alongWithPath path: UIBezierPath, duration: CFTimeInterval, autoreverses: Bool = false) {
|
||||
|
||||
@@ -27,8 +27,8 @@ class ShowViewController: UIViewController {
|
||||
finishButton.tintColor = UIColor.yepTintColor()
|
||||
finishButton.needShowAccessory = true
|
||||
|
||||
pageControlBottomConstraint.constant = Ruler.match(.iPhoneHeights(0, 10, 20, 30))
|
||||
finishButtonBottomConstraint.constant = Ruler.match(.iPhoneHeights(20, 30, 40, 50))
|
||||
pageControlBottomConstraint.constant = Ruler.iPhoneVertical(0, 10, 20, 30).value
|
||||
finishButtonBottomConstraint.constant = Ruler.iPhoneVertical(20, 30, 40, 50).value
|
||||
|
||||
makeUI()
|
||||
}
|
||||
|
||||
@@ -248,7 +248,8 @@ class SkillHomeViewController: CustomNavigationBarViewController {
|
||||
if let skillID = skill?.ID {
|
||||
if let
|
||||
myUserID = YepUserDefaults.userID.value,
|
||||
me = userWithUserID(myUserID, inRealm: Realm()) {
|
||||
realm = try? Realm(),
|
||||
me = userWithUserID(myUserID, inRealm: realm) {
|
||||
|
||||
let predicate = NSPredicate(format: "skillID = %@", skillID)
|
||||
|
||||
@@ -456,7 +457,7 @@ extension SkillHomeViewController: UIImagePickerControllerDelegate, UINavigation
|
||||
|
||||
switch mediaType {
|
||||
|
||||
case kUTTypeImage as String:
|
||||
case kUTTypeImage as! String:
|
||||
|
||||
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
|
||||
|
||||
@@ -507,11 +508,13 @@ extension SkillHomeViewController: UIImagePickerControllerDelegate, UINavigation
|
||||
}, completion: { [weak self] success in
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = Realm()
|
||||
guard let realm = try? Realm() else {
|
||||
return
|
||||
}
|
||||
|
||||
if let userSkill = userSkillWithSkillID(skillID, inRealm: realm) {
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
userSkill.coverURLString = skillCoverURLString
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class YepTabBarController: UITabBarController {
|
||||
// }
|
||||
// }
|
||||
|
||||
if let items = tabBar.items as? [UITabBarItem] {
|
||||
if let items = tabBar.items {
|
||||
|
||||
let titles = [
|
||||
NSLocalizedString("Chats", comment: ""),
|
||||
|
||||
@@ -18,8 +18,6 @@ class ChatLeftTextCell: ChatBaseCell {
|
||||
|
||||
func makeUI() {
|
||||
|
||||
let fullWidth = UIScreen.mainScreen().bounds.width
|
||||
|
||||
let halfAvatarSize = YepConfig.chatCellAvatarSize() / 2
|
||||
|
||||
avatarImageView.center = CGPoint(x: YepConfig.chatCellGapBetweenWallAndAvatar() + halfAvatarSize, y: halfAvatarSize)
|
||||
@@ -83,7 +81,7 @@ class ChatLeftTextCell: ChatBaseCell {
|
||||
let size = textContentTextView.sizeThatFits(CGSize(width: textContentLabelWidth, height: CGFloat.max))
|
||||
|
||||
// lineHeight 19.088, size.height 35.5 (1 line) 54.5 (2 lines)
|
||||
textContentTextView.textAlignment = ((size.height - textContentTextView.font.lineHeight) < 20) ? .Center : .Left
|
||||
textContentTextView.textAlignment = ((size.height - textContentTextView.font!.lineHeight) < 20) ? .Center : .Left
|
||||
|
||||
if size.width != textContentLabelWidth {
|
||||
textContentLabelWidth += YepConfig.ChatCell.magicWidth
|
||||
|
||||
@@ -105,7 +105,7 @@ class ChatRightTextCell: ChatRightBaseCell {
|
||||
let size = textContentTextView.sizeThatFits(CGSize(width: textContentLabelWidth, height: CGFloat.max))
|
||||
|
||||
// lineHeight 19.088, size.height 35.5 (1 line) 54.5 (2 lines)
|
||||
textContentTextView.textAlignment = ((size.height - textContentTextView.font.lineHeight) < 20) ? .Center : .Left
|
||||
textContentTextView.textAlignment = ((size.height - textContentTextView.font!.lineHeight) < 20) ? .Center : .Left
|
||||
|
||||
if size.width != textContentLabelWidth {
|
||||
textContentLabelWidth += YepConfig.ChatCell.magicWidth
|
||||
|
||||
@@ -28,8 +28,8 @@ class EditSkillCell: UITableViewCell {
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
skillLabelLeadingConstraint.constant = Ruler.match(.iPhoneWidths(15, 20, 25))
|
||||
removeButtonTrailingConstraint.constant = Ruler.match(.iPhoneWidths(15, 20, 25))
|
||||
skillLabelLeadingConstraint.constant = Ruler.iPhoneHorizontal(15, 20, 25).value
|
||||
removeButtonTrailingConstraint.constant = Ruler.iPhoneHorizontal(15, 20, 25).value
|
||||
|
||||
removeButton.addTarget(self, action: "tryRemoveSkill", forControlEvents: .TouchUpInside)
|
||||
}
|
||||
@@ -47,5 +47,5 @@ class EditSkillCell: UITableViewCell {
|
||||
removeSkillAction?(self, userSkill)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -55,10 +55,10 @@ class ProfileHeaderCell: UICollectionViewCell {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if (error != nil) {
|
||||
println("\(location) reverse geodcode fail: \(error.localizedDescription)")
|
||||
println("\(location) reverse geodcode fail: \(error?.localizedDescription)")
|
||||
}
|
||||
|
||||
if let placemarks = placemarks as? [CLPlacemark] {
|
||||
if let placemarks = placemarks {
|
||||
if let firstPlacemark = placemarks.first {
|
||||
self?.locationLabel.text = firstPlacemark.locality ?? (firstPlacemark.name ?? firstPlacemark.country)
|
||||
}
|
||||
|
||||
@@ -102,8 +102,6 @@ class ProfileSocialAccountImagesCell: UICollectionViewCell {
|
||||
iconImageView.tintColor = UIColor.lightGrayColor()
|
||||
nameLabel.textColor = UIColor.lightGrayColor()
|
||||
|
||||
let providerName = socialAccount.description.lowercaseString
|
||||
|
||||
var accountEnabled = false
|
||||
|
||||
if let profileUser = profileUser {
|
||||
|
||||
@@ -20,14 +20,14 @@ class FriendRequestView: UIView {
|
||||
switch self {
|
||||
case .Add(let prompt):
|
||||
return prompt
|
||||
case .Consider(let prompt, let _):
|
||||
case .Consider(let prompt, _):
|
||||
return prompt
|
||||
}
|
||||
}
|
||||
|
||||
var friendRequestID: String? {
|
||||
switch self {
|
||||
case .Consider(let _, let friendRequestID):
|
||||
case .Consider( _, let friendRequestID):
|
||||
return friendRequestID
|
||||
default:
|
||||
return nil
|
||||
|
||||
@@ -172,7 +172,7 @@ class MediaControlView: UIView {
|
||||
let startPoint = CGPointZero
|
||||
let endPoint = CGPoint(x:0, y: rect.height)
|
||||
|
||||
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0)
|
||||
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, CGGradientDrawingOptions(rawValue: 0))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,11 +61,10 @@ class MediaPreviewView: UIView {
|
||||
mediaControlView.playState = .Playing
|
||||
|
||||
if
|
||||
let videoFileURL = NSFileManager.yepMessageVideoURLWithName(message.localAttachmentName),
|
||||
let asset = AVURLAsset(URL: videoFileURL, options: [:]),
|
||||
let playerItem = AVPlayerItem(asset: asset) {
|
||||
let videoFileURL = NSFileManager.yepMessageVideoURLWithName(message.localAttachmentName) {
|
||||
let playerItem = AVPlayerItem(asset: AVURLAsset(URL: videoFileURL, options: [:]))
|
||||
|
||||
let x = NSFileManager.defaultManager().fileExistsAtPath(videoFileURL.path!)
|
||||
//let x = NSFileManager.defaultManager().fileExistsAtPath(videoFileURL.path!)
|
||||
|
||||
playerItem.seekToTime(kCMTimeZero)
|
||||
|
||||
@@ -75,8 +74,12 @@ class MediaPreviewView: UIView {
|
||||
|
||||
player.addPeriodicTimeObserverForInterval(CMTimeMakeWithSeconds(0.1, Int32(NSEC_PER_SEC)), queue: nil, usingBlock: { time in
|
||||
|
||||
if player.currentItem.status == .ReadyToPlay {
|
||||
let durationSeconds = CMTimeGetSeconds(player.currentItem.duration)
|
||||
guard let currentItem = player.currentItem else {
|
||||
return
|
||||
}
|
||||
|
||||
if currentItem.status == .ReadyToPlay {
|
||||
let durationSeconds = CMTimeGetSeconds(currentItem.duration)
|
||||
let currentSeconds = CMTimeGetSeconds(time)
|
||||
let coundDownTime = Double(Int((durationSeconds - currentSeconds) * 10)) / 10
|
||||
self.mediaControlView.timeLabel.text = "\(coundDownTime)"
|
||||
@@ -99,7 +102,7 @@ class MediaPreviewView: UIView {
|
||||
|
||||
mediaView.videoPlayerLayer.player = player
|
||||
|
||||
mediaView.videoPlayerLayer.player.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
|
||||
mediaView.videoPlayerLayer.player?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
|
||||
|
||||
mediaView.videoPlayerLayer.addObserver(self, forKeyPath: "readyForDisplay", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
|
||||
|
||||
@@ -208,8 +211,8 @@ class MediaPreviewView: UIView {
|
||||
func hide() {
|
||||
if let message = message {
|
||||
if message.mediaType == MessageMediaType.Video.rawValue {
|
||||
mediaView.videoPlayerLayer.player.pause()
|
||||
mediaView.videoPlayerLayer.player.removeObserver(self, forKeyPath: "status")
|
||||
mediaView.videoPlayerLayer.player?.pause()
|
||||
mediaView.videoPlayerLayer.player?.removeObserver(self, forKeyPath: "status")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +296,7 @@ class MediaPreviewView: UIView {
|
||||
|
||||
delay(0.3) {
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
self.mediaView.videoPlayerLayer.player.play()
|
||||
self.mediaView.videoPlayerLayer.player?.play()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ class MessageToolbar: UIToolbar {
|
||||
let messageTextViewConstraintsV = NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[messageTextView]-8-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewsDictionary)
|
||||
|
||||
let textContainerInset = messageTextView.textContainerInset
|
||||
let constant = ceil(messageTextView.font.lineHeight + textContainerInset.top + textContainerInset.bottom)
|
||||
let constant = ceil(messageTextView.font!.lineHeight + textContainerInset.top + textContainerInset.bottom)
|
||||
messageTextViewHeightConstraint = NSLayoutConstraint(item: messageTextView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: constant)
|
||||
|
||||
let constraintsH = NSLayoutConstraint.constraintsWithVisualFormat("H:|[micButton(48)][messageTextView][moreButton(==micButton)]|", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: nil, views: viewsDictionary)
|
||||
@@ -344,7 +344,7 @@ class MessageToolbar: UIToolbar {
|
||||
|
||||
if let draft = conversation.draft {
|
||||
|
||||
realm.write { [weak self] in
|
||||
let _ = try? realm.write { [weak self] in
|
||||
if let strongSelf = self {
|
||||
draft.messageToolbarState = strongSelf.state.rawValue
|
||||
|
||||
@@ -358,7 +358,7 @@ class MessageToolbar: UIToolbar {
|
||||
let draft = Draft()
|
||||
draft.messageToolbarState = state.rawValue
|
||||
|
||||
realm.write {
|
||||
let _ = try? realm.write {
|
||||
conversation.draft = draft
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class VoiceRecordButton: UIView {
|
||||
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
|
||||
super.touchesMoved(touches, withEvent: event)
|
||||
|
||||
if let touch = touches.first as? UITouch {
|
||||
if let touch = touches.first {
|
||||
let location = touch.locationInView(touch.view)
|
||||
|
||||
if location.y < 0 {
|
||||
|
||||
@@ -19,7 +19,7 @@ class YepShape: CAShapeLayer {
|
||||
|
||||
let bottomGap = height / CGFloat(tan(M_PI / 3))
|
||||
let bottomWidth = width - bottomGap * 2
|
||||
let gapSideLenth = bottomGap * 2
|
||||
//let gapSideLenth = bottomGap * 2
|
||||
|
||||
rectanglePath.moveToPoint(CGPointMake(0, 0))
|
||||
rectanglePath.addLineToPoint(CGPointMake(width, 0))
|
||||
@@ -36,7 +36,7 @@ class YepShape: CAShapeLayer {
|
||||
|
||||
let bottomGap = height / CGFloat(tan(M_PI / 3))
|
||||
let bottomWidth = width - bottomGap * 2
|
||||
let gapSideLenth = bottomGap * 2
|
||||
//let gapSideLenth = bottomGap * 2
|
||||
|
||||
rectanglePath.moveToPoint(CGPointMake(bottomGap, 0))
|
||||
rectanglePath.addLineToPoint(CGPointMake(bottomGap + bottomWidth, 0))
|
||||
@@ -66,9 +66,9 @@ class YepRefreshView: UIView {
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
let x = shapeHeight / CGFloat(tan(M_PI / 3))
|
||||
//let x = shapeHeight / CGFloat(tan(M_PI / 3))
|
||||
|
||||
var bottomWidth = shapeWidth - x * 2
|
||||
//var bottomWidth = shapeWidth - x * 2
|
||||
|
||||
let shape1 = YepShape()
|
||||
let shape2 = YepShape()
|
||||
@@ -170,7 +170,7 @@ class YepRefreshView: UIView {
|
||||
|
||||
var positions = [CGPoint]()
|
||||
|
||||
for i in 0..<count {
|
||||
for _ in 0..<count {
|
||||
positions.append(CGPoint(x: randomInRange(-200...200), y: randomInRange(-200...200)))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user