swift Zero to App:使用Firebase进行开发(适用于iOS - Google I / O 2016)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift Zero to App:使用Firebase进行开发(适用于iOS - Google I / O 2016)相关的知识,希望对你有一定的参考价值。

//
//  ViewController.swift
//  ZeroToApp
//

import UIKit
import Firebase
import FBSDKLoginKit
import Photos

struct ChatMessage {
  var name: String!
  var message: String!
  var image: UIImage?
}

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

  // Outlets
  @IBOutlet weak var messageTextField: UITextField!
  @IBOutlet weak var sendButton: UIButton!
  @IBOutlet weak var tableView: UITableView!

  // Useful app properties
  let imagePicker = UIImagePickerController()
  var messages: [ChatMessage]!
  var username: String!

  // Firebase services
  var database: FIRDatabase!
  var auth: FIRAuth!
  var storage: FIRStorage!

  override func viewDidLoad() {
    super.viewDidLoad()

    // Initialize navigation bar
    self.title = "Zero To App"
    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Log in",
                                                        style: UIBarButtonItemStyle.Plain,
                                                        target: self,
                                                        action: #selector(toggleAuthState))
    navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Camera,
                                                       target: self,
                                                       action: #selector(selectImage))

    // Initialize send button
    sendButton.addTarget(self,
                         action: #selector(sendMessage),
                         forControlEvents: .TouchUpInside)

    // Initialize UIImagePicker
    imagePicker.delegate = self

    // Initialize other properties
    messages = []
    username = "iOS"

    // Initialize UITableView
    tableView.delegate = self
    tableView.dataSource = self
    let nib = UINib(nibName: "ChatMessageTableViewCell", bundle: nil)
    tableView.registerNib(nib, forCellReuseIdentifier: "chatMessageCell")

    // Initialize Database, Auth, Storage
    database = FIRDatabase.database()
    auth = FIRAuth.auth()
    storage = FIRStorage.storage()

    // Listen for when child nodes get added to the collection
    let chatRef = database.reference().child("chat")
    chatRef.observeEventType(.ChildAdded, withBlock: { (snapshot) -> Void in
      // Get the chat message from the snapshot and add it to the UI
      let data = snapshot.value as! Dictionary<String, String>
      guard let name = data["name"] as String! else { return }
      guard let message = data["message"] as String! else { return }
      let chatMessage = ChatMessage(name: name, message: message, image: nil)
      self.addMessage(chatMessage)
    })

    // Observe auth state change
    self.auth.addAuthStateDidChangeListener { (auth, user) in
      if (user != nil) {
        self.username = user?.displayName
        self.navigationItem.rightBarButtonItem?.title = "Log out"
      } else {
        self.username = "iOS"
        self.navigationItem.rightBarButtonItem?.title = "Log in"
      }
    }

  }

  // Send a chat message
  func sendMessage(sender: AnyObject) {
    // Create chat message
    let chatMessage = ChatMessage(name: self.username, message: messageTextField.text!, image: nil)
    messageTextField.text = ""

    // Create a reference to our chat message
    let chatRef = database.reference().child("chat")

    // Push the chat message to the database
    chatRef.childByAutoId().setValue(["name": chatMessage.name, "message": chatMessage.message])
  }

  // Show a popup when the user asks to sign in
  func toggleAuthState() {
    if (auth.currentUser != nil) {
      // Allow the user to sign out
      do {
        try auth.signOut()
      } catch {}
    } else {
      // Log in to Facebook
      let login = FBSDKLoginManager()
      login.logInWithReadPermissions(["public_profile"], fromViewController: self, handler: { (result, error) in
        if (error != nil || result.isCancelled) {
          print(error)
        } else {
          // Log in to Firebase via Facebook
          let credential = FIRFacebookAuthProvider.credentialWithAccessToken(result.token.tokenString)
          FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
            if (error != nil) {
              print(error)
            }
          }
        }
      })
    }
  }

  // Handle photo uploads button
  func selectImage() {
    imagePicker.allowsEditing = false
    imagePicker.sourceType = .PhotoLibrary

    presentViewController(imagePicker, animated: true, completion: nil)
  }

  // pragma mark - UIImagePickerDelegate overrides
  func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

    // Get local file URLs
    guard let image: UIImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
    let imageData = UIImagePNGRepresentation(image)!
    guard let imageURL: NSURL = info[UIImagePickerControllerReferenceURL] as? NSURL else { return }

    // Get a reference to the location where we'll store our photos
    let photosRef = storage.reference().child("chat_photos")

    // Get a reference to store the file at chat_photos/<FILENAME>
    let photoRef = photosRef.child("\(NSUUID().UUIDString).png")

    // Upload file to Firebase Storage
    let metadata = FIRStorageMetadata()
    metadata.contentType = "image/png"
    photoRef.putData(imageData, metadata: metadata).observeStatus(.Success) { (snapshot) in
      // When the image has successfully uploaded, we get it's download URL
      let text = snapshot.metadata?.downloadURL()?.absoluteString
      // Set the download URL to the message box, so that the user can send it to the database
      self.messageTextField.text = text
    }

    // Clean up picker
    dismissViewControllerAnimated(true, completion: nil)
  }

  func addMessage(var chatMessage: ChatMessage) {
    // Handle remote image messages
    if (chatMessage.message.containsString("https://firebasestorage.googleapis.com")) {
      self.storage.referenceForURL(chatMessage.message).dataWithMaxSize(25 * 1024 * 1024, completion: { (data, error) -> Void in
        let image = UIImage(data: data!)
        chatMessage.image = image!
        self.messages.append(chatMessage)
        self.tableView.reloadData()
        self.scrollToBottom()
      })
    // Handle asset library messages
    } else if (chatMessage.message.containsString("assets-library://")) {
      let assetURL = NSURL(string: chatMessage.message)
      let assets = PHAsset.fetchAssetsWithALAssetURLs([assetURL!], options: nil)
      let asset: PHAsset = assets.firstObject as! PHAsset

      let manager = PHImageManager.defaultManager()
      manager.requestImageForAsset(asset, targetSize: CGSize(width: 100.0, height: 100.0), contentMode: .AspectFit, options: nil, resultHandler: {(result, info)->Void in
        chatMessage.image = result!
        self.messages.append(chatMessage)
        self.tableView.reloadData()
        self.scrollToBottom()
      })
    // Handle regular messages
    } else {
      self.messages.append(chatMessage)
      self.tableView.reloadData()
      self.scrollToBottom()
    }
  }

  func scrollToBottom() {
    if (self.messages.count > 8) {
      let bottomOffset = CGPoint(x: 0, y: tableView.contentSize.height - tableView.bounds.size.height)
      tableView.setContentOffset(bottomOffset, animated: true)
    }
  }

  // pragma mark - UITableViewDataSource overrides
  func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("chatMessageCell", forIndexPath: indexPath) as! ChatMessageTableViewCell
    let chatMessage = messages[indexPath.row]
    cell.nameLabel.text = chatMessage.name
    cell.messageLabel.text = chatMessage.message
    cell.photoView.image = chatMessage.image
    return cell
  }

  // pragma mark - UITableViewDelegate overrides
  func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    let chatMessage = messages[indexPath.row]
    if (chatMessage.image != nil) {
      return 345.0
    } else {
      return 58.0
    }
  }

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return messages.count
  }

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
  }

  // Create a chat message from a FIRDataSnapshot
  func chatMessageFromSnapshot(snapshot: FIRDataSnapshot) -> ChatMessage? {
    let data = snapshot.value as! Dictionary<String, String>
    guard let name = data["name"] as String! else { return nil }
    guard let message = data["message"] as String! else { return nil }
    let chatMessage = ChatMessage(name: name, message: message, image: nil)
    return chatMessage
  }
}

///
//  AppDelegate.swift
//  ZeroToApp
//

import UIKit
import Firebase
import FBSDKCoreKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?


  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Configure Firebase SDK
    FIRApp.configure()
    
    // Configure Facebook SDK
    FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    return true
  }

  func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
  }

}

以上是关于swift Zero to App:使用Firebase进行开发(适用于iOS - Google I / O 2016)的主要内容,如果未能解决你的问题,请参考以下文章

Zero To One

zero to one

ORA-01476: divisor is equal to zero解决方法

转发 Learning Go?—?from zero to hero

首先通过Fluent API在EF代码中实现Zero或One to Zero或One关系

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: xxxx