Skip to content

Upgrade iOS SDK to v200.7 #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions arcgis_map_sdk_ios/ios/arcgis_map_sdk_ios.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ A new Flutter project.
s.source = { :path => '.' }
s.source_files = 'arcgis_map_sdk_ios/Sources/**/*'
s.dependency 'Flutter'
s.dependency 'ArcGIS-Runtime-Toolkit-iOS'
s.platform = :ios, '13.0'
s.platform = :ios, '16.0'

# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
Expand Down
6 changes: 3 additions & 3 deletions arcgis_map_sdk_ios/ios/arcgis_map_sdk_ios/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ import PackageDescription
let package = Package(
name: "arcgis_map_sdk_ios",
platforms: [
.iOS("14.0")
.iOS("16.0")
],
products: [
.library(name: "arcgis-map-sdk-ios", targets: ["arcgis_map_sdk_ios"])
],
dependencies: [
.package(url: "https://github.com/Esri/arcgis-runtime-ios", .upToNextMinor(from: "100.15.0")),
.package(url: "https://github.com/Esri/arcgis-maps-sdk-swift", .upToNextMinor(from: "200.7.0")),
],
targets: [
.target(
name: "arcgis_map_sdk_ios",
dependencies: [
.product(name: "ArcGIS", package: "arcgis-runtime-ios")
.product(name: "ArcGIS", package: "arcgis-maps-sdk-swift")
]
),
]
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ class GraphicsParser {
self.registrar = registrar
}

func parse(dictionary: Dictionary<String, Any>) throws -> [AGSGraphic] {
func parse(dictionary: Dictionary<String, Any>) throws -> [Graphic] {
let type = dictionary["type"] as! String

let newGraphics: [AGSGraphic]
let newGraphics: [Graphic]
switch (type) {
case "point":
newGraphics = try! parsePoint(dictionary)
Expand All @@ -31,26 +31,29 @@ class GraphicsParser {
throw ParseException(message: "Unknown graphic type: \(type)")
}

let attributes = dictionary["attributes"] as? Dictionary<String, Any>
if let attributes = attributes {
newGraphics.forEach {
$0.attributes.addEntries(from: attributes)
// Apply attributes to each graphic, if present
if let attributes = dictionary["attributes"] as? [String: Any] {
newGraphics.forEach { graphic in
for (key, value) in attributes {
graphic.setAttributeValue(value, forKey: key)
}
}
}

return newGraphics
}

private func parsePoint(_ dictionary: [String: Any]) throws -> [AGSGraphic] {
private func parsePoint(_ dictionary: [String: Any]) throws -> [Graphic] {
let point: LatLng = try! JsonUtil.objectOfJson(dictionary["point"] as! Dictionary<String, Any>)

let graphic = AGSGraphic()
let graphic = Graphic()
graphic.geometry = point.toAGSPoint()
graphic.symbol = try! parseSymbol(dictionary["symbol"] as! Dictionary<String, Any>)

return [graphic]
}

private func parsePolyline(_ dictionary: [String: Any]) throws -> [AGSGraphic] {
private func parsePolyline(_ dictionary: [String: Any]) throws -> [Graphic] {
let payload: PathPayload = try! JsonUtil.objectOfJson(dictionary)

return try payload.paths.map { coordinates in
Expand All @@ -59,28 +62,28 @@ class GraphicsParser {
throw ParseException(message: "Size of coordinates need to be at least 2. Got \(array)")
}
if(array.count > 2) {
return AGSPoint(x: array[0], y: array[1], z: array[2], spatialReference: .wgs84())
return Point(x: array[0], y: array[1], z: array[2], spatialReference: .wgs84)
}
return AGSPoint(x: array[0], y: array[1], spatialReference: .wgs84())
return Point(x: array[0], y: array[1], spatialReference: .wgs84)
}

let graphic = AGSGraphic()
graphic.geometry = AGSPolyline(points: points)
let graphic = Graphic()
graphic.geometry = Polyline(points: points)
graphic.symbol = try! parseSymbol(dictionary["symbol"] as! Dictionary<String, Any>)

return graphic
}
}

private func parsePolygon(_ dictionary: [String: Any]) throws -> [AGSGraphic] {
private func parsePolygon(_ dictionary: [String: Any]) throws -> [Graphic] {
let payload: PolygonPayload = try! JsonUtil.objectOfJson(dictionary)

return payload.rings.map { ring in
let graphic = AGSGraphic()
let graphic = Graphic()
let points = ring.map { coordinate in
AGSPoint(x: coordinate[0], y: coordinate[1], spatialReference: .wgs84())
Point(x: coordinate[0], y: coordinate[1], spatialReference: .wgs84)
}
graphic.geometry = AGSPolygon(points: points)
graphic.geometry = Polygon(points: points)
graphic.symbol = try! parseSymbol(dictionary["symbol"] as! Dictionary<String, Any>)

return graphic
Expand All @@ -89,7 +92,7 @@ class GraphicsParser {

// region symbol parsing

func parseSymbol(_ dictionary: [String: Any]) throws -> AGSSymbol {
func parseSymbol(_ dictionary: [String: Any]) throws -> Symbol {
let type = dictionary["type"] as! String;
switch (type) {
case "simple-marker":
Expand All @@ -105,48 +108,48 @@ class GraphicsParser {
}
}

private func parseSimpleMarkerSymbol(_ dictionary: [String: Any]) -> AGSSymbol {
private func parseSimpleMarkerSymbol(_ dictionary: [String: Any]) -> Symbol {
let payload: SimpleMarkerSymbolPayload = try! JsonUtil.objectOfJson(dictionary)

let symbol = AGSSimpleMarkerSymbol()
let symbol = SimpleMarkerSymbol()
symbol.color = payload.color.toUIColor()
symbol.size = payload.size
symbol.outline = AGSSimpleLineSymbol(
symbol.outline = SimpleLineSymbol(
style: .solid,
color: payload.outlineColor.toUIColor(),
width: payload.outlineWidth
)
return symbol
}

private func parseSimpleFillMarkerSymbol(_ dictionary: [String: Any]) -> AGSSymbol {
private func parseSimpleFillMarkerSymbol(_ dictionary: [String: Any]) -> Symbol {
let payload: SimpleFillSymbolPayload = try! JsonUtil.objectOfJson(dictionary)

let symbol = AGSSimpleFillSymbol()
let symbol = SimpleFillSymbol()
symbol.color = payload.fillColor.toUIColor()

let outline = AGSSimpleLineSymbol()
let outline = SimpleLineSymbol()
outline.width = payload.outlineWidth
outline.color = payload.outlineColor.toUIColor()
symbol.outline = outline

return symbol
}

private func parsePictureMarkerSymbol(_ dictionary: [String: Any]) -> AGSSymbol {
private func parsePictureMarkerSymbol(_ dictionary: [String: Any]) -> Symbol {
let payload: PictureMarkerSymbolPayload = try! JsonUtil.objectOfJson(dictionary)

if(!payload.assetUri.isWebUrl()) {
let uiImage = getFlutterUiImage(payload.assetUri)
let symbol = AGSPictureMarkerSymbol(image: uiImage!)
let symbol = PictureMarkerSymbol(image: uiImage!)
symbol.width = payload.width
symbol.height = payload.height
symbol.offsetX = payload.xOffset
symbol.offsetY = payload.yOffset
return symbol
}

let symbol = AGSPictureMarkerSymbol(url: URL(string: payload.assetUri)!)
let symbol = PictureMarkerSymbol(url: URL(string: payload.assetUri)!)
symbol.width = payload.width
symbol.height = payload.height
symbol.offsetX = payload.xOffset
Expand All @@ -161,9 +164,9 @@ class GraphicsParser {
return UIImage(named: path!)
}

private func parseSimpleLineSymbol(_ dictionary: [String: Any]) -> AGSSymbol {
private func parseSimpleLineSymbol(_ dictionary: [String: Any]) -> Symbol {
let payload: SimpleLineSymbolPayload = try! JsonUtil.objectOfJson(dictionary)
let symbol = AGSSimpleLineSymbol()
let symbol = SimpleLineSymbol()

if let color = payload.color {
symbol.color = color.toUIColor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,38 @@
import Foundation
import ArcGIS

class ManualLocationDataSource: AGSLocationDataSource {
final class CustomLocationProvider: LocationProvider {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename the file name to be CustomLocationProvider.swift?

private var locationContinuation: AsyncThrowingStream<Location, Error>.Continuation?
private var headingContinuation: AsyncThrowingStream<Double, Error>.Continuation?


// Exposed stream
var locations: AsyncThrowingStream<Location, Error> {
AsyncThrowingStream { continuation in
self.locationContinuation = continuation
}
}

var headings: AsyncThrowingStream<Double, Error> {
AsyncThrowingStream { continuation in
self.headingContinuation = continuation
}
}

// Push location from outside
public func setNewLocation(_ position: UserPosition) {
let loc = AGSLocation(
let loc = Location(
position: position.latLng.toAGSPoint(),
horizontalAccuracy: position.accuracy ?? 0,
velocity: position.velocity ?? 0,
verticalAccuracy: position.accuracy ?? 0,
speed: position.velocity ?? 0,
course: position.heading ?? 0,
lastKnown: false
isLastKnown: false
)
didUpdate(loc)
locationContinuation?.yield(loc)
if let heading = position.heading {
headingContinuation?.yield(heading)
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//
// Created by Tarek Tolba on 29/04/2025.
//

import SwiftUI
import ArcGIS
import CoreLocation


struct MapContentView: View {
@ObservedObject var viewModel: MapViewModel

init(viewModel: MapViewModel) {
self.viewModel = viewModel
}

var body: some View {
MapViewReader { mapViewProxy in
MapView(
map: viewModel.map,
viewpoint: viewModel.viewpoint,
graphicsOverlays: [viewModel.defaultGraphicsOverlay]
)
.attributionBarHidden(viewModel.attributionBarHidden)
.locationDisplay(viewModel.locationDisplay)
.contentInsets(viewModel.contentInsets)
.interactionModes(viewModel.interactionModes)
.onViewpointChanged(kind: .centerAndScale) { newViewpoint in
viewModel.viewpoint = newViewpoint
}
.onScaleChanged { scale in
viewModel.onScaleChanged?(scale)
}
.onVisibleAreaChanged { polygon in
viewModel.onVisibleAreaChanged?(polygon)
}
.onChange(of: viewModel.map.basemap?.loadStatus) { newValue in
if let newValue {
viewModel.onLoadStatusChanged?(newValue)
}
}
.task {
// Store the mapViewProxy for external access
viewModel.mapViewProxy = mapViewProxy
}
.onDisappear {
viewModel.stopLocationDataSource()
// Clear the mapViewProxy reference when view disappears
viewModel.mapViewProxy = nil
}
.ignoresSafeArea(edges: .all)
}
}
}


class MapViewModel: ObservableObject {
let map = Map()
let locationDisplay = LocationDisplay()

@Published var viewpoint: Viewpoint
@Published var mapViewProxy: MapViewProxy?
@Published var attributionBarHidden: Bool = false
@Published var contentInsets: EdgeInsets = EdgeInsets()
@Published var interactionModes: MapViewInteractionModes = .all
@Published var defaultGraphicsOverlay = GraphicsOverlay()

var onScaleChanged: ((Double) -> Void)?
var onVisibleAreaChanged: ((Polygon) -> Void)?
var onLoadStatusChanged: ((LoadStatus) -> Void)?

init(viewpoint : Viewpoint) {
self.viewpoint = viewpoint
}

/// Stops the location data source.
func stopLocationDataSource() {
Task {
await locationDisplay.dataSource.stop()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,3 @@ struct AnimationOptions: Codable {
var animationCurve: String
}

extension AnimationOptions {
func arcgisAnimationCurve() -> AGSAnimationCurve {
switch animationCurve {
case "linear":
return .linear
case "easeIn":
return .easeInCirc
case "easeOut":
return .easeOutCirc
case "easeInOut":
return .easeInOutCirc
default:
return .linear
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct LatLng: Codable {
}

extension LatLng {
func toAGSPoint() -> AGSPoint {
AGSPoint(x: longitude, y: latitude, spatialReference: .wgs84())
func toAGSPoint() -> Point {
Point(x: longitude, y: latitude, spatialReference: .wgs84)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ enum PolylineStyle: String, Codable {
case shortDot
case solid

func toAGSStyle() -> AGSSimpleLineSymbolStyle {
func toAGSStyle() -> SimpleLineSymbol.Style {
switch (self) {
case .dash:
return .dash
Expand All @@ -48,7 +48,7 @@ enum PolylineStyle: String, Codable {
case .longDashDotDot:
return .longDashDot
case .none:
return .null
return .noLine
case .shortDash:
return .shortDash
case .shortDashDot:
Expand All @@ -68,7 +68,7 @@ enum MarkerPlacement: String, Codable {
case end
case beginEnd

func toAGSStyle() -> AGSSimpleLineSymbolMarkerPlacement {
func toAGSStyle() -> SimpleLineSymbol.MarkerPlacement {
switch (self) {
case .begin:
return .begin
Expand All @@ -88,12 +88,12 @@ enum MarkerStyle: String, Codable {
self = try MarkerStyle(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .none
}

func toAGSStyle() -> AGSSimpleLineSymbolMarkerStyle {
func toAGSStyle() -> SimpleLineSymbol.MarkerStyle {
switch (self) {
case .arrow:
return .arrow
case .none:
return .none
return .noMarkers
}
}
}
Loading