{"id":13778351,"url":"https://github.com/firebase/geofire-objc","last_synced_at":"2025-05-16T07:07:17.641Z","repository":{"id":18427775,"uuid":"21611008","full_name":"firebase/geofire-objc","owner":"firebase","description":"GeoFire for Objective-C - Realtime location queries with Firebase","archived":false,"fork":false,"pushed_at":"2024-08-21T17:37:59.000Z","size":1513,"stargazers_count":442,"open_issues_count":26,"forks_count":183,"subscribers_count":82,"default_branch":"master","last_synced_at":"2025-05-11T09:03:01.786Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/firebase.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.txt","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-07-08T12:01:06.000Z","updated_at":"2025-04-13T11:39:58.000Z","dependencies_parsed_at":"2024-01-05T20:58:10.678Z","dependency_job_id":"c7c5f5df-14a4-4f61-8a4a-6d3b27abfa96","html_url":"https://github.com/firebase/geofire-objc","commit_stats":{"total_commits":145,"total_committers":29,"mean_commits":5.0,"dds":0.6482758620689655,"last_synced_commit":"63aa31fa7790554f4e5da8e3f573e49eb6542ed7"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firebase%2Fgeofire-objc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firebase%2Fgeofire-objc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firebase%2Fgeofire-objc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firebase%2Fgeofire-objc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/firebase","download_url":"https://codeload.github.com/firebase/geofire-objc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485065,"owners_count":22078767,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T18:00:53.203Z","updated_at":"2025-05-16T07:07:12.628Z","avatar_url":"https://github.com/firebase.png","language":"Objective-C","readme":"# GeoFire for iOS — Realtime location queries with Firebase\n\nGeoFire is an open-source library for iOS that allows you to store and query a\nset of keys based on their geographic location.\n\nAt its heart, GeoFire simply stores locations with string keys. Its main\nbenefit however, is the possibility of querying keys within a given geographic\narea - all in realtime.\n\nGeoFire uses the [Firebase](https://firebase.google.com/?utm_source=geofire-objc) database for\ndata storage, allowing query results to be updated in realtime as they change.\nGeoFire *selectively loads only the data near certain locations, keeping your\napplications light and responsive*, even with extremely large datasets.\n\nA compatible GeoFire client is also available for [Java](https://github.com/firebase/geofire-java)\nand [JavaScript](https://github.com/firebase/geofire-js).\n\n### Integrating GeoFire with your data\n\nGeoFire is designed as a lightweight add-on to Firebase. However, to keep things\nsimple, GeoFire stores data in its own format and its own location within\nyour Firebase database. This allows your existing data format and security rules to\nremain unchanged and for you to add GeoFire as an easy solution for geo queries\nwithout modifying your existing data.\n\n### Example Usage\nAssume you are building an app to rate bars and you store all information for a\nbar, e.g. name, business hours and price range, at `/bars/\u003cbar-id\u003e`. Later, you\nwant to add the possibility for users to search for bars in their vicinity. This\nis where GeoFire comes in. You can store the location for each bar using\nGeoFire, using the bar IDs as GeoFire keys. GeoFire then allows you to easily\nquery which bar IDs (the keys) are nearby. To display any additional information\nabout the bars, you can load the information for each bar returned by the query\nat `/bars/\u003cbar-id\u003e`.\n\n\n## Upgrading GeoFire\n\n### Upgrading from Geofire 1.x to 2.x\n\nWith the \n[expansion of Firebase at Google I/O 2016](https://firebase.googleblog.com/2016/05/firebase-expands-to-become-unified-app-platform.html) \nand onwards, we've added a number of new features to Firebase, and have changed \ninitialization to incorporate them more easily. See our \n[setup instructions](https://firebase.google.com/docs/ios/setup) for more info \non installing and initializing the Firebase SDK.\n\n### Upgrading from GeoFire 1.0.x to 1.1.x\n\nWith the release of GeoFire for iOS 1.1.0, this library now uses [the new query functionality found in\nFirebase 2.0.0](https://firebase.googleblog.com/2014/11/firebase-now-with-more-querying.html). As a\nresult, you will need to upgrade to Firebase 2.x.x and add a new `.indexOn` rule to your Security\nand Firebase Rules to get the best performance. You can view [the updated rules\nhere](https://github.com/firebase/geofire-js/blob/master/examples/securityRules/rules.json)\nand [read our docs for more information about indexing your data](https://firebase.google.com/docs/database/security/indexing-data).\n\n\n## Downloading GeoFire for iOS\n\nIf you're using [CocoaPods](http://cocoapods.org/?q=geofire), add the following \nto your `Podfile`:\n\n```ruby\npod 'GeoFire', '~\u003e 4.0'\n```\n\n### Using GeoFire with Swift\n\nGeoFire supports Swift out of the box! In order to use GeoFire and Swift from CocoaPods, add the `use_frameworks!` line to your `Podfile`, like so:\n\n```ruby\nuse_frameworks!\n\npod 'GeoFire', '~\u003e 4.0'\n```\n\n## Getting Started with Firebase\n\nGeoFire uses Firebase Realtime Database to store location data. You can [sign up here for a free\naccount](https://firebase.google.com/console/?utm_source=geofire-objc).\n\n## GeoFire for iOS Quickstart\n\nSee the `examples/SFVehicles` folder for a working example of a project using GeoFire via CocoaPods.\n\n### GeoFire\n\nA `GeoFire` object is used to read and write geo location data to your Firebase database\nand to create queries. To create a new `GeoFire` instance you need to attach it to a Firebase database reference:\n\n##### Objective-C\n```objective-c\nFIRDatabaseRef *geofireRef = [[FIRDatabase database] reference];\nGeoFire *geoFire = [[GeoFire alloc] initWithFirebaseRef:geofireRef];\n```\n\n##### Swift\n```swift\nlet geofireRef = Database.database().reference()\nlet geoFire = GeoFire(firebaseRef: geofireRef)\n```\n\nNote that you can point your reference to anywhere in your Firebase database, but don't\nforget to [set up security rules for\nGeoFire](https://github.com/firebase/geofire-js/blob/master/examples/securityRules).\n\n#### Setting location data\n\nIn GeoFire you can set and query locations by string keys. To set a location for a key\nsimply call the `setLocation:forKey` method:\n\n##### Objective-C\n```objective-c\n[geoFire setLocation:[[CLLocation alloc] initWithLatitude:37.7853889 longitude:-122.4056973]\n              forKey:@\"firebase-hq\"];\n```\n\n##### Swift\n```swift\ngeoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973), forKey: \"firebase-hq\")\n```\n\nAlternatively a callback can be passed which is called once the server\nsuccessfully saves the location:\n\n##### Objective-C\n```objective-c\n[geoFire setLocation:[[CLLocation alloc] initWithLatitude:37.7853889 longitude:-122.4056973]\n              forKey:@\"firebase-hq\"\n withCompletionBlock:^(NSError *error) {\n     if (error != nil) {\n         NSLog(@\"An error occurred: %@\", error);\n     } else {\n         NSLog(@\"Saved location successfully!\");\n     }\n }];\n```\n\n##### Swift\n```swift\ngeoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973), forKey: \"firebase-hq\") { (error) in\n  if (error != nil) {\n    print(\"An error occured: \\(error)\")\n  } else {\n    print(\"Saved location successfully!\")\n  }\n}\n```\n\nTo remove a location and delete the location from your database simply call:\n\n##### Objective-C\n```objective-c\n[geoFire removeKey:@\"firebase-hq\"];\n```\n\n##### Swift\n```swift\ngeoFire.removeKey(\"firebase-hq\")\n```\n\n#### Retrieving a location\n\nRetrieving locations happens with callbacks. If the key is not present in\nGeoFire, the callback will be called with `nil`. If an error occurred, the\ncallback is passed the error and the location will be `nil`.\n\n##### Objective-C\n```objective-c\n[geoFire getLocationForKey:@\"firebase-hq\" withCallback:^(CLLocation *location, NSError *error) {\n    if (error != nil) {\n        NSLog(@\"An error occurred getting the location for \\\"firebase-hq\\\": %@\", [error localizedDescription]);\n    } else if (location != nil) {\n        NSLog(@\"Location for \\\"firebase-hq\\\" is [%f, %f]\",\n              location.coordinate.latitude,\n              location.coordinate.longitude);\n    } else {\n        NSLog(@\"GeoFire does not contain a location for \\\"firebase-hq\\\"\");\n    }\n}];\n```\n\n##### Swift\n```swift\ngeoFire.getLocationForKey(\"firebase-hq\") { (location, error) in\n  if (error != nil) {\n    print(\"An error occurred getting the location for \\\"firebase-hq\\\": \\(error.localizedDescription)\")\n  } else if (location != nil) {\n    print(\"Location for \\\"firebase-hq\\\" is [\\(location.coordinate.latitude), \\(location.coordinate.longitude)]\")\n  } else {\n    print(\"GeoFire does not contain a location for \\\"firebase-hq\\\"\")\n  }\n}\n```\n\n### Geo Queries\n\nGeoFire allows you to query all keys within a geographic area using `GFQuery`\nobjects. As the locations for keys change, the query is updated in realtime and fires events\nletting you know if any relevant keys have moved. `GFQuery` parameters can be updated\nlater to change the size and center of the queried area.\n\n##### Objective-C\n```objective-c\nCLLocation *center = [[CLLocation alloc] initWithLatitude:37.7832889 longitude:-122.4056973];\n// Query locations at [37.7832889, -122.4056973] with a radius of 600 meters\nGFCircleQuery *circleQuery = [geoFire queryAtLocation:center withRadius:0.6];\n\n// Query location by region\nMKCoordinateSpan span = MKCoordinateSpanMake(0.001, 0.001);\nMKCoordinateRegion region = MKCoordinateRegionMake(center.coordinate, span);\nGFRegionQuery *regionQuery = [geoFire queryWithRegion:region];\n```\n\n#### Swift\n```swift\nlet center = CLLocation(latitude: 37.7832889, longitude: -122.4056973)\n// Query locations at [37.7832889, -122.4056973] with a radius of 600 meters\nvar circleQuery = geoFire.queryAtLocation(center, withRadius: 0.6)\n\n// Query location by region\nlet span = MKCoordinateSpanMake(0.001, 0.001)\nlet region = MKCoordinateRegionMake(center.coordinate, span)\nvar regionQuery = geoFire.queryWithRegion(region)\n```\n\n#### Receiving events for geo queries\n\nThere are three kinds of events that can occur with a geo query:\n\n1. **Key Entered**: The location of a key now matches the query criteria.\n2. **Key Exited**: The location of a key no longer matches the query criteria.\n3. **Key Moved**: The location of a key changed but the location still matches the query criteria.\n\nKey entered events will be fired for all keys initially matching the query as well as any time\nafterwards that a key enters the query. Key moved and key exited events are guaranteed to be\npreceded by a key entered event.\n\nTo observe events for a geo query you can register a callback with `observeEventType:withBlock:`:\n\n##### Objective-C\n```objective-c\nFIRDatabaseHandle queryHandle = [query observeEventType:GFEventTypeKeyEntered withBlock:^(NSString *key, CLLocation *location) {\n    NSLog(@\"Key '%@' entered the search area and is at location '%@'\", key, location);\n}];\n```\n\n##### Swift\n```swift\n\nvar queryHandle = query.observeEventType(.KeyEntered, withBlock: { (key: String!, location: CLLocation!) in\n  print(\"Key '\\(key)' entered the search area and is at location '\\(location)'\")\n})\n\n```\n\nTo cancel one or all callbacks for a geo query, call\n`removeObserverWithFirebaseHandle:` or `removeAllObservers:`, respectively.\n\n#### Waiting for queries to be \"ready\"\n\nSometimes you want to know when the data for all the initial keys has been\nloaded from the server and the corresponding events for those keys have been\nfired. For example, you may want to hide a loading animation after your data has\nfully loaded. `GFQuery` offers a method to listen for these ready events:\n\n##### Objective-C\n```objective-c\n[query observeReadyWithBlock:^{\n    NSLog(@\"All initial data has been loaded and events have been fired!\");\n}];\n```\n\n##### Swift\n```swift\n\nquery.observeReadyWithBlock({\n  print(\"All initial data has been loaded and events have been fired!\")\n})\n\n```\n\nNote that locations might change while initially loading the data and key moved and key\nexited events might therefore still occur before the ready event was fired.\n\nWhen the query criteria is updated, the existing locations are re-queried and the\nready event is fired again once all events for the updated query have been\nfired. This includes key exited events for keys that no longer match the query.\n\n#### Updating the query criteria\n\nTo update the query criteria you can use the `center` and `radius` properties on\nthe `GFQuery` object. Key exited and key entered events will be fired for\nkeys moving in and out of the old and new search area, respectively. No key moved\nevents will be fired as a result of the query criteria changing; however, key moved\nevents might occur independently.\n\n## Deployment\n\n- `git pull` to update the master branch\n- tag and push the tag for this release\n- `./build.sh` to build a binary\n- From your macbook that already has been granted permissions to Firebase CocoaPods, do `pod trunk push`\n- Update [firebase-versions](https://github.com/firebase/firebase-clients/blob/master/versions/firebase-versions.json) with the changelog for this release.\n- Add the compiled `target/GeoFire.framework.zip` to the release\n\n## Contributing\n\nIf you'd like to contribute to GeoFire for iOS, you'll need to run the\nfollowing commands to get your environment set up:\n\n```bash\n$ git clone https://github.com/firebase/geofire-objc.git\n$ cd geofire-objc\n$ pod install\n$ open Geofire.xcworkspace\n```\n","funding_links":[],"categories":["Helpers","모바일"],"sub_categories":["iOS"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirebase%2Fgeofire-objc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffirebase%2Fgeofire-objc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirebase%2Fgeofire-objc/lists"}