Skip to content

Instantly share code, notes, and snippets.

@forsythetony
Last active December 10, 2016 06:51
Show Gist options
  • Save forsythetony/ef8195059a53cb5d05dd58346f5d79af to your computer and use it in GitHub Desktop.
Save forsythetony/ef8195059a53cb5d05dd58346f5d79af to your computer and use it in GitHub Desktop.
class PAPhotograph {
private static let DEFAULT_UID = ""
private static let DEFAULT_TITLE = ""
private static let DEFAULT_LONG_DESCRIPTION = ""
private static let DEFAULT_DATE_UPLOADED = Date()
private static let DEFAULT_THUMB_URL = ""
private static let DEFAULT_MAIN_URL = ""
private static let DEFAULT_DATE_TAKEN = Date()
private static let DEFAULT_DATE_CONF : Float = 0.0
private static let DEFAULT_LOC_LONGITUDE : CGFloat = 0.0
private static let DEFAULT_LOC_LATITUDE : CGFloat = 0.0
private static let DEFAULT_LOC_STREET = "Any Street"
private static let DEFAULT_LOC_CITY = "Any City"
private static let DEFAULT_LOC_STATE = "Any State"
private static let DEFAULT_LOC_COUNTRY = "Any Country"
private static let DEFAULT_LOC_CONF : Float = 0.0
var uid = ""
var title = ""
var longDescription = ""
var uploadedBy : PAUser?
var dateUploaded : Date?
var thumbnailURL = ""
var thumbnailImage : UIImage?
var mainImageURL = ""
var mainImage : UIImage?
var taggedPeople : [PAPerson]?
var stories : [PAStory] = [PAStory]()
var dateTaken : Date?
var dateTakenConf : Float = 0.0
var locationTaken : PALocation?
var delegate : PAPhotographDelegate?
/// Function Name: fetchStories
///
/// Return Value: Void
///
/// Description: This function will pull all the stories for this photograph from
/// Firebase and alert the delegate upon each new story addition
///
func fetchStories() {
let db_ref = FIRDatabase.database().reference()
let curr_photo_ref = db_ref.child("photographs").child(self.uid)
let stories_ref = curr_photo_ref.child("stories")
stories_ref.observe(.childAdded, with: { snapshot in
if let new_story = PAStory.PAStoryFromSnapshot(snapshot: snapshot ) {
self.stories.append(new_story)
self.delegate?.PAPhotographDidFetchNewStory(story: new_story)
}
})
}
/// Function Name: photographWithSnapshot
///
/// Parameter 'snap': The FIRDataSnapshot used to create the instance
///
/// Return Value: An instance of PAPhotograph created from the FIRDataSnapshot
/// or nil if no instance could be created
///
static func photographWithSnapshot( snap : FIRDataSnapshot ) -> PAPhotograph? {
guard let snapData = snap.value as? Dictionary<String, AnyObject> else { return nil }
let newPhoto = PAPhotograph()
newPhoto.title = snapData[Keys.Photograph.title] as? String ?? PAPhotograph.DEFAULT_TITLE
newPhoto.longDescription = snapData[Keys.Photograph.description] as? String ?? PAPhotograph.DEFAULT_LONG_DESCRIPTION
newPhoto.uid = snap.key
newPhoto.dateTakenConf = snapData[Keys.Photograph.dateTakenConf] as? Float ?? PAPhotograph.DEFAULT_DATE_CONF
if let date_taken = snapData[Keys.Photograph.dateTaken] as? String {
newPhoto.dateTaken = PADateManager.sharedInstance.getDateFromString(str: date_taken, formatType: .FirebaseFull)
}
else {
newPhoto.dateTaken = PAPhotograph.DEFAULT_DATE_TAKEN
newPhoto.dateTakenConf = 0.0
}
newPhoto.mainImageURL = snapData[Keys.Photograph.mainURL] as? String ?? PAPhotograph.DEFAULT_MAIN_URL
newPhoto.thumbnailURL = snapData[Keys.Photograph.thumbURL] as? String ?? PAPhotograph.DEFAULT_THUMB_URL
let location = PALocation()
let lattitude = snapData[Keys.Photograph.locationLatitude] as? CGFloat ?? PAPhotograph.DEFAULT_LOC_LATITUDE
let longitude = snapData[Keys.Photograph.locationLongitude] as? CGFloat ?? PAPhotograph.DEFAULT_LOC_LONGITUDE
let location_city = snapData[Keys.Photograph.locationCity] as? String ?? PAPhotograph.DEFAULT_LOC_CITY
let location_state = snapData[Keys.Photograph.locationState] as? String ?? PAPhotograph.DEFAULT_LOC_STATE
let location_country = snapData[Keys.Photograph.locationCountry] as? String ?? PAPhotograph.DEFAULT_LOC_COUNTRY
location.coordinates = CLLocationCoordinate2D(latitude: CLLocationDegrees(lattitude), longitude: CLLocationDegrees(longitude))
location.city = location_city
location.state = location_state
location.country = location_country
newPhoto.locationTaken = location
return newPhoto
}
}
enum PAPhotoInfoType {
case Text
case LongText
case Date
case Location
case TaggedPeople
case Submitter
case Unknown
}
class PAPhotoInfo {
var title = ""
var uid = ""
var type : PAPhotoInfoType = PAPhotoInfoType.Unknown
init(_title : String, _uid : String, _type : PAPhotoInfoType) {
self.title = _title
self.uid = _uid
self.type = _type
}
}
class PAPhotoInfoText : PAPhotoInfo {
var mainText = ""
var supplementaryText = ""
init(_uuid : String, _title : String, _mainText : String, _supplementaryText : String, _type : PAPhotoInfoType) {
super.init(_title: _title, _uid: _uuid, _type: _type)
self.mainText = _mainText
self.supplementaryText = _supplementaryText
}
}
class PAPhotoInfoLocation : PAPhotoInfo {
var cityName = ""
var stateName = ""
var coordinates : CLLocationCoordinate2D?
var confidence : Float = 0.0
init(_uuid : String, _title : String, _type : PAPhotoInfoType, _cityName : String, _stateName : String, _coordinates : CLLocationCoordinate2D, _confidence : Float) {
super.init(_title: _title, _uid: _uuid, _type: _type)
self.cityName = _cityName
self.stateName = _stateName
self.coordinates = _coordinates
self.confidence = _confidence
}
}
class PAPhotoInfoDate : PAPhotoInfo {
var dateTaken : Date?
var dateTakenConf : Float = 0.0
var dateTakenString = ""
init(_uid : String, _title : String, _type : PAPhotoInfoType, _dateTaken : Date?, _dateTakenConf : Float, _dateTakenString : String) {
super.init(_title: _title, _uid: _uid, _type: _type)
self.dateTaken = _dateTaken
self.dateTakenConf = _dateTakenConf
self.dateTakenString = _dateTakenString
}
}
protocol PAAudioManagerDelegate {
func PAAudioManagerDidUpdateRecordingTime( time : TimeInterval, story : PAStory)
func PAAudioManagerDidFinishRecording( total_time : TimeInterval , story : PAStory)
func PAAudioManagerDidBeginPlayingStory( story : PAStory )
func PAAudioManagerDidUpdateStoryPlayTime( running_time : TimeInterval, total_time : TimeInterval, story : PAStory)
func PAAudioManagerDidFinishPlayingStory( story : PAStory )
}
class PAAudioManager : NSObject {
static let sharedInstance = PAAudioManager()
//
// Other Properties...
//
var delegate : PAAudioManagerDelegate?
// Example of calling the protocol methods. In this function we let the delegate know, through a protocol function,
// that the story play time has been updated.
func beginPlaying() {
guard let p = self.player else { return }
p.play()
self.player_timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { (t) in
self.curr_play_time += 1.0
if let curr_story = self.curr_story {
self.delegate?.PAAudioManagerDidUpdateStoryPlayTime(running_time: self.curr_play_time, total_time: curr_story.recordingLength, story: curr_story)
}
})
}
}
extension PAPhotoInformationViewController : PAAudioManagerDelegate {
func PAAudioManagerDidUpdateStoryPlayTime(running_time: TimeInterval, total_time: TimeInterval, story: PAStory) {
DispatchQueue.main.async {
self.audioPlayerControls.totalTime = total_time
self.audioPlayerControls.currentTime = running_time
}
}
}
class PARepositoryContainer {
private var currRepositories = [String : PARepository]()
private var repositories = [PARepository]()
private func doesRepositoryExistInArray(_ uuid : String) -> Bool {
if self.currRepositories[uuid] != nil {
return true
}
return false
}
var Count : Int {
get {
return self.repositories.count
}
}
func insertRepository(_ newRepo : PARepository) {
if !self.doesRepositoryExistInArray(newRepo.uid) {
self.currRepositories[newRepo.uid] = newRepo
self.repositories.append(newRepo)
}
}
func repositoryAtIndex(_ index : Int) -> PARepository? {
if index >= 0 && index < repositories.count {
return repositories[index]
}
return nil
}
}
class PAAudioManager : NSObject {
// ................
func playStory( story : PAStory ) {
let sourceType = determineSourceTypeForStory(story: story)
self.curr_story = story
switch sourceType {
case .Local:
guard let story_url = story.tempRecordingURL else { return }
if self.isRecording {
TFLogger.log(logString: "Can't play, already recording...")
return
}
do {
try player = AVAudioPlayer(contentsOf: story_url)
player?.play()
self.delegate?.PAAudioManagerDidBeginPlayingStory(story: story)
self.beginPlaying()
} catch let err {
TFLogger.log(str: "Error playing audio from local source", err: err)
}
case .Network:
guard let network_url = URL(string: story.recordingURL) else
{
TFLogger.log(logString: "The string %@ could not be converted into a URL", arguments: story.recordingURL)
return
}
if self.isRecording {
TFLogger.log(logString: "Can't play, already recording...")
return
}
do {
let story_data = try Data(contentsOf: network_url)
do {
try player = AVAudioPlayer(data: story_data)/
player?.play()
self.delegate?.PAAudioManagerDidBeginPlayingStory(story: story)
self.beginPlaying()
} catch let err {
TFLogger.log(str: "Error playing audio from network source", err: err)
}
}
catch let data_err {
TFLogger.log(str: "There was an error downloading the audio over the network", err: data_err)
}
default:
TFLogger.log(logString: "Could not determine the audio source type for story -> %@", arguments: story.getFirebaseFriendlyArray().description)
return
}
}
// ................
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment