For the map canvas, you need to reuse the code from https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/canvas.html#embedding-map-canvas in your standalone application to create your own canvas and sync it with the layers from your QgsProject instance in your script. With your newly canvas, you will be able to get the reference to the canvas and set your extent.
You may try using the following logic (combined from these two other answers PYQGIS signal for layer tree when active layer changed & Getting Layer Properties of QGIS on standalone application using PyQGIS API) for the active layer part.
It does not depend of iface and you can get the "active layer" (PS: tested inside QGIS not in the standalone app but could help you solve your issue as no iface anywhere)
# Create your standalone TreeView, no iface deps
# Layer Tree View
layerTreeRoot = QgsProject.instance().layerTreeRoot()
layerTreeModel = QgsLayerTreeModel(layerTreeRoot)
layerTreeView = QgsLayerTreeView()
layerTreeView.setModel(layerTreeModel)
layoutWidgetLayout = QHBoxLayout()
layoutWidgetLayout.addWidget(layerTreeView)
layerWidget = QWidget()
layerWidget.setLayout(layoutWidgetLayout)
# Set the logic to listen to active layer
def test(lyr):
print(lyr.id())
layerTreeView.currentLayerChanged.connect(test)
# Then show the component
layerWidget.show()
# If you click on the layer, it will return the layer id
# If you rather want to set manually the active layer, use the method
# layerTreeView.setCurrentLayer(your_layer) # See https://qgis.org/api/classQgsLayerTreeView.html