In this section, you’ll connect the span from the search operation with other spans from the individual operations that build the results on screen.
In the TheMetStore.swift, fetchObjects(for:) has multiple smaller operations. First it gets a collection of IDs of the search results matching the keyword, then it gets the full object for each ID in an individual network request.
The duration of the whole search operation is directly proportional to the number of IDs, and the duration of each network operation.
To start, you’ll create a span around TheMetService.getObject() which is called inside the loop. Add this line at the beginning of the loop:
And remember to end the span at the end of the loop:
childSpan.end()
Build and run the app. No need to do any searches, the initial search is enough.
Open your Grafana portal and open “Traces”
Each of the spans are sent individually and there is nothing connecting them. It might seem like it’s easy to relate the spans together since they are in order, but they are coming now from one user only. Once you have multiple users and the timelines overlap, it will be much more complicated to relate the spans together with a quick look. The whole idea of visual representations is about a quick look.
To define a parent for a span, it needs to be set on the span builder before the span is created. Go to OTelSpans.swift and change the method declaration of createSpan() to:
The default parameter value of nil ensures that you don’t need to update the function calls across your application, and the parent span is set on the build only if it’s not nil.
Go back to TheMetStore.swift and change the creation of childSpan to the following:
let childSpan = OTelSpans.createSpan(
scopeName: "TheMet-Tracing",
name: "FetchingObject",
parentSpan: span)
Build and run the app. Like last time, don’t do any additional searches and look at the traces on Grafana:
You’ll see only one span. Open its details and you’ll be able to see all the child spans connected to it.
The visual timeline now shows all the spans together. The main span now groups all the child spans with it.
You can see there is an empty area within the main span before the first child span appears. This is where the first network request to load the object IDs.
The network requests are done through TheMetService. You can create spans there but they won’t be connected to the parent span, unless you pass the span itself as a parameter to the methods in the service.
This might be counter intuitive as you’ll mix tracing concerns into your method declarations between the parameters you need, and tracing. Wouldn’t it be nice if the tracing code didn’t show up in your APIs and you’d be able to magically connect spans to a parent if it exists without the necessity of passing spans as parameters across your code?
Luckily, Swift 5.5 introduced Task Locals for this purpose.
In the next section, you’ll use @TaskLocal to simplify the connection of spans together without affecting you APIs or having to pass around Observability objects around your code.
See forum comments
This content was released on Oct 24 2025. The official support period is 6-months
from this date.
In this section, you’ll connect the span from the search operation with other spans from the individual operations that build the results on screen.
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
Previous: Attaching Attributes to Spans
Next: Using TaskLocal to Connect Spans
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.