Skip to content

Instantly share code, notes, and snippets.

@Scanerrr
Last active June 15, 2022 17:04
Show Gist options
  • Save Scanerrr/6d3e45c586f1e2c5adbcf5ff8c005c5e to your computer and use it in GitHub Desktop.
Save Scanerrr/6d3e45c586f1e2c5adbcf5ff8c005c5e to your computer and use it in GitHub Desktop.
Apple mapkitJS places example
import { useCallback, useState } from "react";
import { useMap } from "./useMap";
import { useSearch } from "./useSearch";
export default function AppleMap() {
const { mapkit, map, mapRef } = useMap();
const search = useSearch();
const [value, setValue] = useState("");
const [adressesList, setAddressesList] = useState(null);
const handleChange = useCallback((e) => {
setValue(e.target.value);
}, []);
const drawAnnotation = useCallback(
(place) => {
// Calc the new region
const myRegion = new mapkit.CoordinateRegion(
new mapkit.Coordinate(
place.coordinate.latitude,
place.coordinate.longitude
),
new mapkit.CoordinateSpan(0.01, 0.01)
);
map.region = myRegion;
// Add the new annotation
const myAnnotation = new mapkit.MarkerAnnotation(
new mapkit.Coordinate(
place.coordinate.latitude,
place.coordinate.longitude
),
{
color: "#9b6bcc",
title: place.name,
subtitle: place.formattedAddress,
}
);
map.addAnnotation(myAnnotation);
},
[map, mapkit]
);
const handleSearch = useCallback(() => {
if (!search || !value) return;
search.search(value, (error, data) => {
if (error) {
console.error(error);
return;
}
setAddressesList(
data?.places.map(({ formattedAddress }) => formattedAddress)
);
// Clean up the map of old searches
map.removeAnnotations(map.annotations);
data?.places.forEach(drawAnnotation);
});
}, [search, value, drawAnnotation, map]);
return (
<div className="App">
<h1>MapkitJS example</h1>
<div>
<input type="text" onChange={handleChange} value={value} />
<div>
<button onClick={handleSearch}>Search</button>
</div>
</div>
<small>Result: {adressesList?.length}</small>
<ul>
{!!adressesList?.length ? (
adressesList.map((address) => <li key={address}>{address}</li>)
) : (
<li>Not found</li>
)}
</ul>
<div ref={mapRef} style={{ width: "500px", height: "500px" }}></div>
</div>
);
}
import { useEffect, useRef, useState } from "react";
import { useMapkit } from "./useMapkit";
export const useMap = () => {
const mapkit = useMapkit();
const mapRef = useRef(null);
const [map, setMap] = useState();
useEffect(() => {
if (mapkit && mapRef.current) {
const newMap = new mapkit.Map(mapRef.current);
setMap(newMap);
}
}, [mapkit, mapRef]);
// Clean up the map on unmount
useEffect(() => {
return () => {
if (map) {
map.destroy();
}
};
}, []);
return { mapkit, map, mapRef };
};
/* eslint-disable no-undef */
import React, { useState } from "react";
import load from "little-loader";
const TOKEN = "";
export const useMapkit = () => {
const [lib, setLib] = useState();
React.useEffect(() => {
if (!lib) {
load("https://cdn.apple-mapkit.com/mk/5.x.x/mapkit.js", () => {
// init mapkit
mapkit.init({
authorizationCallback: (done) => {
done(TOKEN);
},
});
setLib(mapkit);
});
}
}, [lib]);
return lib;
};
import { useEffect, useState } from "react";
import { useMapkit } from "./useMapkit";
export const useSearch = () => {
const mapkit = useMapkit();
const [search, setSearch] = useState();
useEffect(() => {
if (mapkit) {
const newSearch = new mapkit.Search();
setSearch(newSearch);
}
}, [mapkit]);
return search;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment