Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Ariba Siddiqui
MapKit Directions
Commits
118673de
Commit
118673de
authored
Nov 29, 2021
by
Ariba Siddiqui
Browse files
Merge branch 'main' into 'main'
Search Function: added comments See merge request
!1
parents
59db5e27
2a54c0a2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Location Tutorial.xcodeproj/project.xcworkspace/xcuserdata/febra.xcuserdatad/UserInterfaceState.xcuserstate
View file @
118673de
No preview for this file type
Location Tutorial/LocationSearch.swift
View file @
118673de
...
@@ -11,6 +11,7 @@ import MapKit
...
@@ -11,6 +11,7 @@ import MapKit
class
LocationService
:
NSObject
,
ObservableObject
{
class
LocationService
:
NSObject
,
ObservableObject
{
// Differnt search states
enum
LocationStatus
:
Equatable
{
enum
LocationStatus
:
Equatable
{
case
idle
case
idle
case
noResults
case
noResults
...
@@ -19,6 +20,9 @@ class LocationService: NSObject, ObservableObject {
...
@@ -19,6 +20,9 @@ class LocationService: NSObject, ObservableObject {
case
result
case
result
}
}
// queryFragment used in view gets updated every time the user types something
// default status is idle
// searchResults contains all the results from the queries
@Published
var
queryFragment
:
String
=
""
@Published
var
queryFragment
:
String
=
""
@Published
private(set)
var
status
:
LocationStatus
=
.
idle
@Published
private(set)
var
status
:
LocationStatus
=
.
idle
@Published
private(set)
var
searchResults
:
[
MKLocalSearchCompletion
]
=
[]
@Published
private(set)
var
searchResults
:
[
MKLocalSearchCompletion
]
=
[]
...
@@ -26,15 +30,21 @@ class LocationService: NSObject, ObservableObject {
...
@@ -26,15 +30,21 @@ class LocationService: NSObject, ObservableObject {
private
var
queryCancellable
:
AnyCancellable
?
private
var
queryCancellable
:
AnyCancellable
?
private
let
searchCompleter
:
MKLocalSearchCompleter
!
private
let
searchCompleter
:
MKLocalSearchCompleter
!
// initiate the search completer, set the delegate on self
init
(
searchCompleter
:
MKLocalSearchCompleter
=
MKLocalSearchCompleter
())
{
init
(
searchCompleter
:
MKLocalSearchCompleter
=
MKLocalSearchCompleter
())
{
self
.
searchCompleter
=
searchCompleter
self
.
searchCompleter
=
searchCompleter
super
.
init
()
super
.
init
()
self
.
searchCompleter
.
delegate
=
self
self
.
searchCompleter
.
delegate
=
self
// receive a stream from the queryFragment in the view
// debounce (wait) for 250miliseconds before pushing the event further
// sink returns the updated string after waiting the specified amount of time
queryCancellable
=
$
queryFragment
queryCancellable
=
$
queryFragment
.
receive
(
on
:
DispatchQueue
.
main
)
.
receive
(
on
:
DispatchQueue
.
main
)
.
debounce
(
for
:
.
milliseconds
(
250
),
scheduler
:
RunLoop
.
main
,
options
:
nil
)
.
debounce
(
for
:
.
milliseconds
(
250
),
scheduler
:
RunLoop
.
main
,
options
:
nil
)
.
sink
(
receiveValue
:
{
fragment
in
.
sink
(
receiveValue
:
{
fragment
in
// if fragment isn't empty then set the queryFrament to the current updated string
self
.
status
=
.
isSearching
self
.
status
=
.
isSearching
if
!
fragment
.
isEmpty
{
if
!
fragment
.
isEmpty
{
self
.
searchCompleter
.
queryFragment
=
fragment
self
.
searchCompleter
.
queryFragment
=
fragment
...
@@ -46,8 +56,12 @@ class LocationService: NSObject, ObservableObject {
...
@@ -46,8 +56,12 @@ class LocationService: NSObject, ObservableObject {
}
}
}
}
// every time the queryFragment gets updated these functions get called
extension
LocationService
:
MKLocalSearchCompleterDelegate
{
extension
LocationService
:
MKLocalSearchCompleterDelegate
{
func
completerDidUpdateResults
(
_
completer
:
MKLocalSearchCompleter
)
{
func
completerDidUpdateResults
(
_
completer
:
MKLocalSearchCompleter
)
{
// query the current input, filter out the results that have subtitles
// results with no subtitles are usually countries and cities
// remove filter if you want to get points of interest as well
self
.
searchResults
=
completer
.
results
.
filter
({
$0
.
subtitle
==
""
})
self
.
searchResults
=
completer
.
results
.
filter
({
$0
.
subtitle
==
""
})
self
.
status
=
completer
.
results
.
isEmpty
?
.
noResults
:
.
result
self
.
status
=
completer
.
results
.
isEmpty
?
.
noResults
:
.
result
}
}
...
...
Location Tutorial/MapSerachView.swift
View file @
118673de
...
@@ -23,6 +23,10 @@ struct ContentView: View {
...
@@ -23,6 +23,10 @@ struct ContentView: View {
Section
(
header
:
Text
(
"Search"
))
{
Section
(
header
:
Text
(
"Search"
))
{
ZStack
(
alignment
:
.
trailing
)
{
ZStack
(
alignment
:
.
trailing
)
{
TextField
(
"Search"
,
text
:
$
locationService
.
queryFragment
)
TextField
(
"Search"
,
text
:
$
locationService
.
queryFragment
)
// while user is typing input it sends the current query to the location service
// which in turns sets its status to searching; when searching status is set on
// searching then a clock symbol will be shown beside the search box
if
locationService
.
status
==
.
isSearching
{
if
locationService
.
status
==
.
isSearching
{
Image
(
systemName
:
"clock"
)
Image
(
systemName
:
"clock"
)
.
foregroundColor
(
Color
.
gray
)
.
foregroundColor
(
Color
.
gray
)
...
@@ -39,7 +43,8 @@ struct ContentView: View {
...
@@ -39,7 +43,8 @@ struct ContentView: View {
default
:
return
AnyView
(
EmptyView
())
default
:
return
AnyView
(
EmptyView
())
}
}
}
.
foregroundColor
(
Color
.
gray
)
}
.
foregroundColor
(
Color
.
gray
)
// display the results as a list
ForEach
(
locationService
.
searchResults
,
id
:
\
.
self
)
{
ForEach
(
locationService
.
searchResults
,
id
:
\
.
self
)
{
completionResult
in
Text
(
completionResult
.
title
)
completionResult
in
Text
(
completionResult
.
title
)
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment